What should a “unit” be when unit testing?

前端 未结 10 962
梦毁少年i
梦毁少年i 2020-12-28 15:16

On Proggit today I was reading the comment thread on a submission entitled, \"Why Unit Testing Is A Waste of Time\".

I\'m not really concerned with premise of the ar

相关标签:
10条回答
  • 2020-12-28 15:42

    In general, the smaller you can make your units, the more useful and effective your unit tests will be. The whole point of units tests is to be able to localize any newly introduced bug to a small part of the code.

    0 讨论(0)
  • 2020-12-28 15:42

    Change the size of the unit until it is no longer trivial? Who the hell defined the unit of code as a single function or method anyway!?

    If it is too difficult to test a "unit" defined as a method, then it is likely that the method is too large or complicated for authoring a unit test.

    I follow a similar methodology suggested by rwmnau, and test at the method level. In addition to creating one test per method, I create additional tests for the different code paths in each method. At times, stressing all of the code paths can become complicated. My challenge is to try to avoid writing the types of methods unless there is no better solution in terms of performance and code complexity.

    I also use mocks to test contracts between components.

    0 讨论(0)
  • 2020-12-28 15:43

    I'd say a unit is the smallest meaningful portion of work that can be separated from other steps in pseudocode.

    For example, if you're trying to do a series of steps to process some data, like

    1. scan the dataset for the min, max, median, mean
    2. generate a histogram
    3. generate a remapping function
    4. remap the data
    5. output the data

    Each of those steps would be a 'unit', and the entire series is itself also a 'unit' (to test that the cohesion between each one is working). Any one of these steps could be four functions (for the first step, if the programmer is running four loops), or one function, or whatever, but in the end, known inputs should give known outputs.

    0 讨论(0)
  • 2020-12-28 15:45

    I suspect that "unit testing" is a misused term. Nowadays, the term isn't just used to refer to testing a small piece of code, but it's used for any test that's automated.

    I tend to write my tests before writing my code, so I can't tell you when I first write it if it's going to cause the creation of a few new lines, a new method, or a new class.

    So, in a word: mu.

    0 讨论(0)
  • 2020-12-28 15:47

    Nothing is trivial, if you take into account the Murphy's Law.

    Jokes apart and assuming an OO environement, I approach Unit Testing taking a class as the unit, because often the various methods modify the internal state and I want to be sure that the state between various methods is consistent.

    Unfortunately, often the only way to check consistency is to invoke various method of a class to see if they fail or not.

    0 讨论(0)
  • 2020-12-28 15:48

    The question is old and there's no precise answer but I think that "anything that makes sense" or "smallest piece that can be usefully tested" can be refined a little bit.

    There's an excellent article blatantly named "Unit tests aren't tests". The title is a click-bait and it is a great read on its own but I will highlight only relevant points here.

    There’s this idea in physics called “emergence”, where simple systems interacting with simple rules give rise to complex systems acting by effectively different rules. For example, atoms are relatively well-understood, self-contained models. Chuck enough of them in a box and suddenly you have the entire field of solid-state physics. ... Code exhibits emergence too. Enough interacting units and your program is vastly more complex than the sum of its parts. Even if each unit is well-behaved and works according to its unit tests, the bulk of the complexity is in their integration.

    Basically try to organize unit tests around "composable units" i.e. something that is less susceptible to effects of emergence when composed together - but tests still should be simple and fast enough to be called "unit tests". Effects of emergence can't be fully eliminated and some complexity will "hide" between the units anyway - however it should be relatively small amount of complexity that can be handled by integration/system tests (which is reflected in Test Pyramid structure).

    Unfortunately high composability and effects of emergence can't be measured instrumentally, I can only give couple of thoughts from the top of my head:

    • heavy usage of mocks and stubs is a smell. It's very easy to employ mocks and report nearly 100% coverage without writing any useful tests.
    • pure immutable units are more composable. In pure functional programming it is common to "unit test" at very high level.
    • for a poorly designed system there's no "right" level of unit tests. It will exhibit emergence regardless of whatever units you try to test. This is why it's a common advice to invest in integration tests while refactoring some spaghetti-coded legacy system.
    0 讨论(0)
提交回复
热议问题