Timeline for Avoid Test duplication if a function created via TDD has an implementation detail that is later used in other functions
Current License: CC BY-SA 4.0
15 events
| when toggle format | what | by | license | comment | |
|---|---|---|---|---|---|
| Jan 9 at 21:38 | comment | added | David Mason | I'm using c#. There is no possibility in the language to create invariants for my types. At least not integrated in the language itself. There might be third party libraries though, but I don't want to have another dependency... | |
| Jan 9 at 16:25 | vote | accept | David Mason | ||
| Jan 9 at 15:41 | review | Close votes | |||
| Jan 10 at 13:34 | |||||
| Jan 9 at 15:22 | comment | added | amon | You have access to a wealth of QA techniques, not just tests. For example, you're using a language with a static type system. Use it to prove that the Parts are already valid, no further check required. If the PartsCollection class has an invariant that it will always be valid, other classes need not do this check. If temporarily-invalid collections are necessary, consider defining a separate class that just holds data but no logic – avoid methods like Init() or ThrowIfInvalid(). Related techniques are called the "typestate pattern" or "make invalid states unrepresentable". | |
| Jan 9 at 13:59 | answer | added | Ewan | timeline score: 1 | |
| Jan 9 at 13:38 | answer | added | VoiceOfUnreason | timeline score: 2 | |
| Jan 9 at 12:56 | answer | added | Doc Brown | timeline score: 4 | |
| Jan 9 at 12:49 | answer | added | Bart van Ingen Schenau | timeline score: 4 | |
| Jan 9 at 12:41 | comment | added | freakish | I don't know what language you use, but most languages allow some kind of test parametrization (or even code generation). So you can create one test which tests both apis the same way. And so apis become parameters. That way you avoid duplication and don't need special treatment. | |
| Jan 9 at 12:40 | comment | added | Ewan | yeah it seems like if you already have tests for PartsCollection then you have 50 odd valid/invalid sample data sets. You don't need to write 50 more tests, just throw these same input sets at CreateMachineWIthInvalidParts_ShouldError() as data driven tests | |
| Jan 9 at 12:24 | comment | added | Thomas Owens♦ | No. If Parts and PartsCollection are well tested, then I would use line coverage to make sure everything is being executed and boundary coverage analysis to make sure I'm covering the essential cases (in this case, around what the PartsCollection looks like - size 0, size 1 with valid, size 1 with invalid, size 2 with valid, size 2 with mix of valid and invalid). I don't need to make an assertion that the function was called if I see it executed in line coverage. When testing the command, I no longer care about what makes a Part or PartsCollection valid or invalid, just that it is. | |
| Jan 9 at 12:18 | comment | added | David Mason | So you would use a spy to make sure that the throw function is executed? | |
| Jan 9 at 12:05 | comment | added | Thomas Owens♦ | It's also not clear why you wouldn't be testing validity in your Parts and PartsCollection classes. Although this may only end up moving tests closer to where they make sense, if Parts and PartsCollection classes are well tested, when testing your commands, you can assume that they will be correct and you only need to test a small number of cases, perhaps such as 0 invalid parts, 1 invalid part in the collection, 2 valid parts in the collection, and 1 valid and 1 invalid part in the collection. Why or how the part is invalid doesn't matter for the purposes of your command. | |
| Jan 9 at 12:01 | comment | added | Thomas Owens♦ | Something else is wrong in your design. This doesn't look like an approach to commands that I'm familiar with. Most commands have a constructor or perhaps use a builder approach and then have a singular execute method. If you have a complex builder, it could be useful to implement a way to see if the command is valid through the public interface, as well as the execute method. I don't know why this ThrowIfCommandInvalid would be part of the public interface. That would open up some other approaches to which tests are necessary to give the confidence that you need. | |
| Jan 9 at 11:25 | history | asked | David Mason | CC BY-SA 4.0 |