Hot answers tagged

130

The later you test, the more it costs to write tests. The longer a bug lives, the more expensive it is to fix. The law of diminishing returns ensures you can test yourself into oblivion trying to ensure there are no bugs. Buddha taught the wisdom of the middle path. Tests are good. There is such a thing as too much of a good thing. The key is being ...


100

I agree with the rest of the answers but to answer the what is the time difference question directly. Roy Osherove in his book The Art of Unit Testing, Second Edition page 200 did a case study of implementing similarly sized projects with similar teams (skill wise) for two different clients where one team did testing while the other one did not. His ...


100

Should savePeople() be unit tested? Yes. You aren't testing that dataStore.savePerson works, or that the db connection works, or even that the foreach works. You are testing that savePeople fulfills the promise it makes through its contract. Imagine this scenario: someone does a big refactor of the code base, and accidentally removes the forEach part of the ...


75

When do you really have numbers which have no meaning at all? Usually, when the numbers have any meaning, you should assign them to local variables of the test method to make the code more readable and self-explaining. The names of the variables should at least reflect what the variable means, not necessarily its value. Example: const int startBalance = ...


60

No, integration tests should not just duplicate the coverage of unit tests. They may duplicate some coverage, but that's not the point. The point of a unit test is to ensure that a specific small bit of functionality works exactly and completely as intended. A unit test for am_i_old_enough would test data with different ages, certainly the ones near the ...


58

I've left them public for ease of unit testing Ease of writing those tests, maybe. But you are then tightly coupling that class to a bunch of tests that interact with its inner workings. This results in brittle tests: they will likely break as soon as you make changes to the code. This creates a real maintenance headache, that often results in people ...


35

I would normally expect you to exercise the private member functions via the public interface. In this instance I would write different tests to feed different file contexts in, with different data sets present in order to exercise those methods. I don't think your tests should know about those private methods. I think they're part of the implementation, ...


32

Usually this kind of question comes up when people do "test-after" development. Approach this problem from the point of view of TDD, where tests come before the implementation, and ask yourself this question again as an exercise. At least in my application of TDD, which is usually outside-in, I'd not be implementing a function like savePeople after having ...


28

There is only one study I know of which studied this in a "real-world setting": Realizing quality improvement through test driven development: results and experiences of four industrial teams. It is expensive to do this in a sensible way, since it basically means you need to develop the same software twice (or ideally even more often) with similar teams, and ...


23

Done well, developing with unit tests can be faster even without considering the benefits of extras bugs being caught. The fact is, I'm not a good enough coder to simply have my code work as soon as it compiles. When I write/modify code, I have to run the code to make sure it does what I thought it does. At one project, this tended to end up looking like: ...


19

If you're using arbitrary numbers just to see what they do, then what you're really looking for is probably randomly generated test data, or property-based testing. For example, Hypothesis is a cool Python library for this sort of testing, and is based on QuickCheck. Think of a normal unit test as being something like the following: Set up some ...


14

Despite there being a lot of answers already, they are somewhat repetitive and I would like to take a different tack. Unit tests are valuable, if and only if, they increase business value. Testing for testing's sake (trivial or tautological tests), or to hit some arbitrary metric (like code coverage), is cargo-cult programming. Tests are costly, not only in ...


12

The primary value such a test provides is that it makes your implementation refactorable. I used to do a lot of performance optimizations in my career and often found problems with the exact pattern you demonstrated: to save N entities into the database, perform N inserts. It's usually more efficient to do a bulk insert using a single statement. On the ...


11

Should savePeople() be unit tested Yes, it should. But try to write your test conditions in a way that is independent from the implementation. For example, turning your usage example into a unit test: function testSavePeople() { myDataStore = new Store('some connection string', 'password'); myPeople = ['Joe', 'Maggie', 'John']; savePeople(...


10

The short answer is "No". The more interesting part is why/how this situation might arise. I think the confusion is arising because you're trying to adhere to strict testing practices (unit tests vs integration tests, mocking, etc.) for code which doesn't seem to adhere to strict practices. That's not to say the code is "wrong", or that particular ...


9

Your unit test name should provide most of the context. Not from the values of the constants. The name/documentation for a test should be giving the appropriate context and explanation of whatever magic numbers are present within the test. If that is not sufficient, a slight bit of documentation should be able to provide it (whether through the variable ...


9

I think the issue comes from the design. My gut feeling says you either wrote the tests after the code, or that you already had a complete implementation in mind when you started writing the tests, and then you just shoehorned the tests to fit the design. I think this type of trouble can be avoided by remembering the short TDD cycle of making a small ...


8

Another point I like to add to Killian's answer is that unit tests run very quickly, so we can have 1000s of them. An integration test typically takes longer because it is calling web services, databases, or some other external dependency, so we cannot run the same tests (1000s) for integration scenarios as they would take too much time. Also, unit tests ...


8

This depends heavily on the function you are testing. I know lots of cases where the individual numbers do not have a special meaning on their own, but the test case as a whole is constructed thoughtfully and so has a specific meaning. That is what one should document in some way. For example, if foo really is a method testForTriangle which decides if the ...


7

It depends on the person, as well as the complexity and shape of the code you're working with. For me, on most projects, writing unit tests means I get the work done about 25% faster. Yes, even including the time to write the tests. Because the fact of the matter is that software isn't done when you write the code. It is done when you ship it to the ...


7

I agree with @BrianAgnew and @kai, but would like to add more than a comment. While an IDedupeFiler (or whatever) should be tested through its public interface, the OP has decided there is value in testing the individual sub-routines. Irrespective of file size or line count (which is only a rough proxy count for class responsibilites), the OP has decided ...


7

You can do two things: First, use parameterized tests to minimize the duplication of the test code: cases([ [0, [1, 8, 9]], [1, [0, 2, 8, 9, 10]], // more testcases here ]) .it('sample', function(n, expected) { expect(getNeighbors(n)).toEqual(expected); }); Second, partition your testcases into equivalence classes where ...


6

If it is the case that the name of the car isn't publicly available in any way at all, then it makes no sense to test it, because obviously it doesn't matter to any client code. If the name of the car matters, even if you can't actually see it by inspecting the field, then exercise some method that relies on the name being correct and assert against some ...


6

Why do we want to use named Constants instead of numbers? DRY - If I need the value at 3 places, I only want to define it once, so I can change it at one place, if it changes. Give meaning to numbers. If you write several unit tests, each with an assortment of 3 Numbers (startBalance, interest, years ) - I would just pack the values into the unit-test as ...


5

Is this the correct way of testing the script? assert_equal(calculate("Degree", "Sin", 90), Math.sin(90 * Math.PI/180)) This tests if your function behaves identical to the standard library. Not if it behaves the way you expect it to behave. It is better to hardcode the expected result: assert_equal(calculate("Degree", "Sin", 90), 1.0) how am ...


5

Should bakeCookies() be tested? Yes. How should a function like this be unit tested, assuming you think it should? It's hard for me to imagine any kind of unit test that doesn't simply mock dough, pan, and oven, and then assert that methods are called on them. Not really. Look closely at WHAT the function is supposed to do - it is supposed to set the ...


5

Look at the following diagram. It illustrates the relationship between Test-Driven Development (TDD) and Acceptance Test-Driven Development (ATDD): Notice that the inner loop, TDD, is enveloped by the outer loop, ATDD. Requirements (illustrated by the Acceptance Criteria box) drive the creation of automated acceptance tests, which in turn drive the ...


4

From the comments we exchanged, it seems you are not just unfamiliar with the maths, but also with basic numeric computing discipline. First, for god's sake, don't automatically pick an epsilon to makes your tests "pass". If you fudge the epsilons until the error is below epsilon, your tests don't test anything at all and you may ignore really bad precision ...


3

...but in this case the numbers actually have no meaning at all The numbers are being used to call a method so surely the above premise is incorrect. You may not care what the numbers are but that is beside the point. Yes, you could infer what the numbers are used for by some IDE wizardry but it would be far better if you just gave the values names - even ...


3

I think you might benefit from a slight shift in the way you view unit tests. Instead of thinking about them as a way to guarantee that all your code is working, think of them as a way to guarantee that your public interface does what you claim it does. In other words, don't worry about testing the internals at all - write unit tests that prove that when ...



Only top voted, non community-wiki answers of a minimum length are eligible