4 ms·
> This is one of those things that sounds good when you're in college, and sounds, well, horrifying is too strong a word, but it will definitely set off the war
by 51GWERY43 7y ago
> This is one of those things that sounds good when you're in college, and sounds, well, horrifying is too strong a word, but it will definitely set off the warning bells for anyone that's been programming for a decade or more.
To someone that has programmed for a good 2 decades and more, the above sounds like what a college student or junior dev that just found out about TDD would say.
Unit test and integration tests are (bad) substitutes for good and modular design, which should piggyback on a strong type system. I've seen it so often that whenever I read comments like the above I feel the need to create an HN account just to reply to them.
Junior devs in charge of major design decisions create damage that goes way beyond their limited reach. Test code is untested code. Test code is brittle code - especially integration tests are. You need tests because you're using a dynamically typed language? Well, stop using that language for anything that is even remotely complex. Your future senior dev self will thank you.
- growse 7y agoA "good and modular design" with a "strong type system" won't help you when one of your dependencies has an upgrade with a subtle bug that changes the behaviour of your system.
- lucisferre 7y ago> test and integration tests are (bad) substitutes for good and modular design, which should piggyback on a strong type system This sounds completely hand wavy. If the design is in fact modular and built of autonomous components then it should be relatively easy to test and should be tested. Types are no substitute for testing and are completely orthogonal to testing. > Test code is brittle code If this is the case then the code being tested is more than likely brittle as well. Test code reflects the system under test more than anything else. > You need tests because you're using a dynamically typed language No you simply need tests in any language.
- mixedCase 7y ago> Types are no substitute for testing. I don't agree with the person you're replying to that types make tests redundant, but to claim that types can't substitute a large amount of testing can only come from inexperience. Whatever property you can model successfully through a closed type, is a property you never have to test ever again anywhere it's being used. If you have 500 functions that take a NonEmptyString, those are 499 fewer property checks in tests (because you should have one test for the type constructor).
- lucisferre 7y ago> types can't substitute a large amount of testing can only come from inexperience That is a very bold assertion I have seen no evidence for. I write very few tests in Ruby or Javascript aimed at validating types.
- paulintrognon 7y agoIf you don't have tests for everything, how do you check that everything's still working fine? Because the only alternative I see to not thoroughly test code is to check the app by hand to make sure nothing's broken, which is, well... Not as robust as having it checked by a machine.
- eyelidlessness 7y agoI think the idea isn't that you don't thoroughly test, but that types are sufficient tests of certain functionality, and they're significantly more expressive and efficient than their runtime equivalents.
- Syntaf 7y ago> You need tests because you're using a dynamically typed language? I don't really understand the connection between a dynamically typed language and the need for (or lack of) testing. Can you explain what you mean? I've never once felt like the type of language I used defined how important tests were. When I write a unit tests, I'm not looking for syntax errors or a scenario where I'm passing the wrong type in, I'm verifying that the business rules of my domain are being properly enforced. If your unit test is brittle, I'd say that's a pretty awful unit test. You should be isolating the component you're testing and eliminating all external dependencies like in the example below. class ItemRecommenderGuardTest extends TestCase { public function setUp() { $dependency = Phake::mock(Dependency::class); $this->recommenderGuard = new ItemRecommenderGuard( $dependency ); } public function testGuardsInvalidItem() { // business rules deem this item un-recommendable. This unit // test verifies that the guard class properly enforces these rules $item = /* ... */; $this->assertFalse($this->recommenderGuard->isRecommendable($item); } } This test isn't brittle, and it's asserting that an item which does not meet recommendable standards is never recommendable. If someone comes along and modifies the guard class incorrectly, these unit tests are here to maintain the integrity of the system
- kyralis 7y agoTo someone else that has programmed for a good 2 decades or more, the above sounds like cowboy programming that leads to unmaintainable systems. Unit and integration tests are not "substitutes" for good and modular design. Good and modular design work hand in hand with tests to produce reliable, well understood, and maintainable code. The most testable code is usually often the most well separated code. A strong type system provides the third leg of the tripod. It's not replaced by or a replacement for either of the other two. Stop thinking that you're too good for test code. Your future senior dev self will thank you.
- thomascgalvin 7y ago> Unit test and integration tests are (bad) substitutes for good and modular design... That's a complete non-sequitur. You can have spaghetti code that produces a correct result, and you can have a beautiful architecture that produces an incorrect result. Testing is the only way to verify whether or not your code is producing the correct result. You can test by hand or automatically, but the ultimate determination on the correctness of the code relies on a test. It has nothing to do with design.
- Fire-Dragon-DoL 7y agoTesting is a superset of type checking. And people forget the main thing about TDD: The main goal is to validate your design You don't get that with type systems.