What Makes a Good Unit Test? [closed]

2019-01-01 04:38发布

I'm sure most of you are writing lots of automated tests and that you also have run into some common pitfalls when unit testing.

My question is do you follow any rules of conduct for writing tests in order to avoid problems in the future? To be more specific: What are the properties of good unit tests or how do you write your tests?

Language agnostic suggestions are encouraged.

18条回答
骚的不知所云
2楼-- · 2019-01-01 05:05

Let me begin by plugging sources - Pragmatic Unit Testing in Java with JUnit (There's a version with C#-Nunit too.. but I have this one.. its agnostic for the most part. Recommended.)

Good Tests should be A TRIP (The acronymn isn't sticky enough - I have a printout of the cheatsheet in the book that I had to pull out to make sure I got this right..)

  • Automatic : Invoking of tests as well as checking results for PASS/FAIL should be automatic
  • Thorough: Coverage; Although bugs tend to cluster around certain regions in the code, ensure that you test all key paths and scenarios.. Use tools if you must to know untested regions
  • Repeatable: Tests should produce the same results each time.. every time. Tests should not rely on uncontrollable params.
  • Independent: Very important.
    • Tests should test only one thing at a time. Multiple assertions are okay as long as they are all testing one feature/behavior. When a test fails, it should pinpoint the location of the problem.
    • Tests should not rely on each other - Isolated. No assumptions about order of test execution. Ensure 'clean slate' before each test by using setup/teardown appropriately
  • Professional: In the long run you'll have as much test code as production (if not more), therefore follow the same standard of good-design for your test code. Well factored methods-classes with intention-revealing names, No duplication, tests with good names, etc.

  • Good tests also run Fast. any test that takes over half a second to run.. needs to be worked upon. The longer the test suite takes for a run.. the less frequently it will be run. The more changes the dev will try to sneak between runs.. if anything breaks.. it will take longer to figure out which change was the culprit.

Update 2010-08:

  • Readable : This can be considered part of Professional - however it can't be stressed enough. An acid test would be to find someone who isn't part of your team and asking him/her to figure out the behavior under test within a couple of minutes. Tests need to be maintained just like production code - so make it easy to read even if it takes more effort. Tests should be symmetric (follow a pattern) and concise (test one behavior at a time). Use a consistent naming convention (e.g. the TestDox style). Avoid cluttering the test with "incidental details".. become a minimalist.

Apart from these, most of the others are guidelines that cut down on low-benefit work: e.g. 'Don't test code that you don't own' (e.g. third-party DLLs). Don't go about testing getters and setters. Keep an eye on cost-to-benefit ratio or defect probability.

查看更多
弹指情弦暗扣
3楼-- · 2019-01-01 05:07

What you're after is delineation of the behaviours of the class under test.

  1. Verification of expected behaviours.
  2. Verification of error cases.
  3. Coverage of all code paths within the class.
  4. Exercising all member functions within the class.

The basic intent is increase your confidence in the behaviour of the class.

This is especially useful when looking at refactoring your code. Martin Fowler has an interesting article regarding testing over at his web site.

HTH.

cheers,

Rob

查看更多
永恒的永恒
4楼-- · 2019-01-01 05:09

I second the "A TRIP" answer, except that tests SHOULD rely on each other!!!

Why?

DRY - Dont Repeat Yourself - applies to testing as well! Test dependencies can help to 1) save setup time, 2) save fixture resources, and 3) pinpoint to failures. Of course, only given that your testing framework supports first-class dependencies. Otherwise, I admit, they are bad.

Follow up http://www.iam.unibe.ch/~scg/Research/JExample/

查看更多
临风纵饮
5楼-- · 2019-01-01 05:11

Test should originally fail. Then you should write the code that makes them pass, otherwise you run the risk of writing a test that is bugged and always passes.

查看更多
孤独总比滥情好
6楼-- · 2019-01-01 05:13

I like the Right BICEP acronym from the aforementioned Pragmatic Unit Testing book:

  • Right: Are the results right?
  • B: Are all the boundary conditions correct?
  • I: Can we check inverse relationships?
  • C: Can we cross-check results using other means?
  • E: Can we force error conditions to happen?
  • P: Are performance characteristics within bounds?

Personally I feel that you can get pretty far by checking that you get the right results (1+1 should return 2 in a addition function), trying out all the boundary conditions you can think of (such as using two numbers of which the sum is greater than the integer max value in the add function) and forcing error conditions such as network failures.

查看更多
爱死公子算了
7楼-- · 2019-01-01 05:13

Jay Fields has a lot of good advices about writing unit tests and there is a post where he summarize the most important advices. There you will read that you should critically think about your context and judge if the advice is worth to you. You get a ton of amazing answers here, but is up to you decide which is best for your context. Try them and just refactoring if it smells bad to you.

Kind Regards

查看更多
登录 后发表回答