Tag Info

Hot answers tagged

82

In regard to the common definition of unit tests, I'd say no. I've seen simple code made convoluted because of the need to twist it to suit the testing framework (eg interfaces and IoC everywhere making things difficult to follow through layers of interface calls and data that should be obvious passed in by magic). Given the choice between code that is easy ...


65

By making them test just the thing they're about, and not lots of unrelated properties that are true now but might change later. Some examples from my experience. Often systems are supposed to send notifications to their users when certain things happen. With a proper test harness, it's easy to mock email messages and verify that they go out, get to the ...


54

Is writing testable code still good practice even in the absence of tests? First things first, an absence of tests is a way bigger issue than your code being testable or not. Not having unit tests means you're not done with your code/feature. That out of the way, I wouldn't say that it's important to write testable code - it's important to write ...


34

Yes, it is good practice. The reason is that testability is not for the sake of tests. It is for the sake of clarity and understandability that it brings with it. Nobody cares about the tests themselves. It is a sad fact of life that we need large regression test suites because we're not brilliant enough to write perfect code without constantly checking our ...


26

For software to be highly testable, it must be designed and implemented with testing in mind. This is complementary to Killian Foth's answer, where the software is designed according to a contract, and the test is performed to verify that contract. "Designing code for testability" means one will have to learn e.g. mocks, stubs, etc. These are various ways ...


16

Sometimes test code contains snippets of code from third parties, both external and internal to your company. This happens as users file bugs; your tests (such as regression tests) then incorporate the code supplied by them to reproduce. Often, the licensing of such code snippets to reproduce bugs is unclear. So, you should be aware of intellectual ...


14

You can still write unit tests. What your question describes is a scenario in which you have some data sources that your code depends on. These data sources need to produce the same fake data across all of your tests. However, you don't want the clutter associated with setting up responses for every single test. What you need are test fakes A test fake is ...


11

Yes, he's right - writing unit tests does increase your workload, and as you change your code the tests start to fail and you have to update them and that increases your workload even further. However... that applies when you are changing code that is affected by the tests, typically you write code pieces that are tested by some unit tests and then you do ...


10

Shipping tests? Yes. Shipping Unit tests? No. As you say in the comment, problem you may face when running the product on a client computer will include problems such as linking with the wrong dll, generally this is not something a unit test will catch (which will no doubt have mocked the dll out to test the code). Now, shipping an integration test suite, ...


10

The most pragmatic approach is IMHO by not blindly sticking to the model of "not changing the project's code under any circumstances." So my suggestion is: make the code testable first - change the project's code slightly to make sure the out-of-bounds access leads to a reproducible and catchable error. Note that making code testable is very often a ...


8

At some point the value needs to be initialized, and why not closest to consumption? Because you may need to reuse that code, with a different value than the one generated internally. The ability to insert the value you are going to use as a parameter, ensures that you can generate those values based on any time you like, not just "now" (with "now" ...


6

There are a couple of things you can do to make testing software like that easier. First, try to abstract as much as you can into layers that aren't visual. That will let you just write standard unit tests on those lower layers. For example, if you have a button that performs a certain calculation, make sure you have a way to perform that calculation in a ...


6

one of my newbie co-workers says that tests make things more difficult. I think the key here is what things? There are lots of processes involved in software development. Writing executable code is only one of them. If we focus on writing executable(/compilable/etc.) code, then writing tests does make that more difficult, simply because there's more ...


6

I suggest you have one unit test for each linearly independent path through the function. In practice, this means one test, plus an additional test for each branch. To learn more, I suggest you read about Cyclomatic complexity (https://en.wikipedia.org/wiki/Cyclomatic_complexity)


6

It's possible that not every characteristic which contributes to testability is desirable outside the context of testability - I have trouble coming up with a non-test-related justification for the time parameter you cite, for instance - but broadly speaking the characteristics which contribute to testability also contribute to good code regardless of ...


6

It certainly has a cost, but some developers are so accustomed to paying it that they've forgotten the cost is there. For your example, you now have two units instead of one, you've required the calling code to initialize and manage an additional dependency, and while GetTimeOfDay is more testable, you are right back in the same boat testing your new ...


5

The fact that: Some of the logic might make 100+ different lookups. is irrelevant in a context of unit testing. A unit tests focuses on a small part of the code, usually a method, and it is unlikely that a single method needs 100+ lookup tables (if it does, refactoring should be your top concern; testing comes after that). Unless you mean 100+ lookups ...


4

Everything has an interface. When I put my testing hat on, I use a specific world-view to write a test: If something exists, it can be measured. If it can't be measured, it doesn't matter. If it does matter, I just haven't found a way to measure it yet. Requirements prescribe measurable properties, or they are useless. A system fulfils a requirement when ...


4

You don't have to test .NET Framework's code in your specific case, because: You can't inherit from Convert class, since this class is static; even if you could do that, for example if Convert class weren't static: The Convert class has no virtual methods, There are no instance methods, There are no abstract methods, You cannot override static methods in a ...


4

It may seem silly to say it this way, but if you want to be able to test your code, then yes, writing testable code is better. You ask: At some point the value needs to be initialized, and why not closest to consumption? Precisely because, in the example you are referring to, it makes that code untestable. Unless you only run a subset of your tests ...


4

Writing testable code is important if you want to be able to prove that your code actually works. I tend to agree with the negative sentiments about warping your code into heinous contortions just to fit it to a particular test framework. On the other hand, everybody here has, at some point or other, had to deal with that 1,000 line long magic function ...


3

This depends on how your conversion class looks like. If it looks like this: class MyConvert { public static Foo1 ToFoo1(Bar1 bar){...} public static Foo2 ToFoo2(Bar1 bar){...} public static Foo3 ToFoo3(Bar1 bar){...} // ... public static Foo1 ToFoo1(Bar2 bar){...} public static Foo2 ToFoo2(Bar2 bar){...} ...


3

In addition to the answer above, I'd also recommend testing out edge cases - so e.g. -1, 0, and then a large number. You could also test that passing something other than an integer makes the method behave the way it is supposed to behave.


3

A quality of well-written code is that it is robust to change. That is, when a requirements change comes along, the change in the code should be proportional. This is an ideal (and not always achieved), but writing testable code helps get us closer to this goal. Why does it help get us closer? In production, our code operates within the production ...


2

(1) There is a concept of a "death test", in which a failing piece of code would cause a process termination. In order to execute such death test, the test harness need to start a separate process which will execute the piece of code. The termination condition is then taken as the pass or fail criteria. Obviously, not every unit testing framework supports ...


2

Tests are useful when they break: Proactively or Re-actively. Unit Tests are proactive and may be a continuous functional verification while Integration Tests are reactive on a staged/fake data. If the system under consideration is close to/dependent on data more than computation logic, Integration Tests should get more importance. For example, if we are ...


2

He argued that tests were constantly in his way when he tried to implement a new feature. The tests would fail after he had changed the code. So he had to adapt the tests which of course increased his workload. That is the number one way in which tests help implement new features. The tests would fail after he had changed the code. The code ...


2

The fact that your class is a conversion class, the fact that it is static, and the fact that it expands an existing framework class are all irrelevant. This question is an instance of the more general question of black-box vs. white-box testing. In lack of any very good reason to perform white-box testing, all testing should be black-box testing. ...


2

Modifying code to be able to test it has nothing wrong. In fact, one of the points of TDD and unit testing in general is to encourage you to write a more maintainable code. On the other hand, your example illustrates integration, system or functional testing, not unit testing. In unit testing, tests are as independent of the environment as possible, which, ...


2

From my experience, one of the most important and most far-reaching decisions you make when building a program is how you break the code down into units (where "units" is used in its broadest sense). If you are using a class-based OO language, you need to break all the internal mechanisms used to implement the program into some number of classes. Then you ...



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