4 ms·
Disclaimer: I work in statically typed languages. I’ve studied and practiced TDD for years. I’ve even written articles to help beginners. I now only practice
by marsrover 8y ago
Disclaimer: I work in statically typed languages.
I’ve studied and practiced TDD for years. I’ve even written articles to help beginners.
I now only practice it sparingly. Sometimes it makes more sense to write the test first and other times I already know exactly what I want and I know how to make it testable.
An even bigger issue I have is the huge reliance on mocking which leads to completely brittle tests and code that can withstand no change without all hell breaking lose.
Lately I spend more time on acceptance tests, which I do often write first. I use unit testing for non-trival logic.
- kraftman 8y agoI found this set of articles great for using less mocks and creating less brittle tests: https://enterprisecraftsmanship.com/2015/07/06/how-to-do-painless-tdd/ https://enterprisecraftsmanship.com/2015/07/06/how-to-do-pai...
- avinium 8y ago> Lately I spend more time on acceptance tests, which I do often write first. I use unit testing for non-trival logic. What's the difference between acceptance tests and integration tests?
- arenaninja 8y agoIt depends on where you work, but to me acceptance tests run on a browser (e.g.: automate site testing with puppeteer, selenium), while integration tests I would say tests running an API call that's allowed to hit a data store At some places, the only acceptance testing that exists is user acceptance testing, where a user manually interacts with the application to sign off on updates after verifying that it meets the business requirements
- malkia 8y agoMy understandings are: Unit test: tests single function/class, uses fake or mocked data to test for expectations. Test coverage can be used to find spots missed in testing. Integration test: test two or more things in isolation - interaction between two classes, functions, etc. OR more than one system (say micro-service) communicating with another. The rest of the systems are fake/mock or fetch/replay golden data. Unit test should take milliseconds to execute. I'm not actually sure what acceptance test would be?
- Denzel 8y agoYou're right. The definitions of boundaries between acceptance vs. integration tests is fluid and depends upon the team context. In our team, we define the terms less by tactics and more by intent. It's our belief that you can generalize your idea on what acceptance testing means. The intent of an acceptance test is to verify that -- no matter how it's exercised -- the implementation performs the work and outputs the result I expected. Now, you can exercise this implementation with any interface. Of which, a browser is just one interface to your application layer. An HTTP API is yet another interface; a command-line utility is another; etc. We actually have separate acceptance tests at the UI level and the API level. Sometimes even at the _feature_ level, in that it exercises a multi-step multi-result pathway through the application. The engineer responsible for developing a unit of work may or may not implement API level acceptance tests (it's recommended); the reviewing engineer usually writes an automated API level acceptance test that must pass for the merge request to pass from code review -> QA/QC; then the QA/QC engineer implements and runs UI level acceptance tests that must pass to move from QA/QC -> Done. We've found this process to be very effective in reducing our defect rate and improving the quality of our product.
- dionian 8y agoan IT can be used as an AT, but doesnt have to be
- anonytrary 8y ago> I already know exactly what I want and I know how to make it testable. An even bigger issue I have is the huge reliance on mocking which leads to completely brittle tests and code. ... use unit testing for non-trival logic. Couldn't have said it better myself. If you're unsure about the best form of your API, then TDD can be hindering. Tests are important but TDD can be an anti-pattern.
- u801e 8y ago> An even bigger issue I have is the huge reliance on mocking which leads to completely brittle tests and code that can withstand no change without all hell breaking lose. In my opinion, unit tests should only cover code that doesn't have any side-effects or interact with external dependencies. For example, if you have a method that handles a HTTP request, extracts information from that request, queries a DB, processes the results from the DB
- u801e 8y agoMods, you can delete the post above and this post. Somehow, it was posted before I finished typing it (the finished version is at this link https://news.ycombinator.com/item?id=17763711 https://news.ycombinator.com/item?id=17763711).
- u801e 8y ago> An even bigger issue I have is the huge reliance on mocking which leads to completely brittle tests and code that can withstand no change without all hell breaking lose. In my opinion, unit tests should only cover code that doesn't have any side-effects or interact with external dependencies. For example, suppose you have a method that handles a HTTP request, extracts information from that request, create a database query, query the database, processes the results from the DB, generates a HTTP response, and then sends the response back to the client. You can easily factor out the parts that don't have external dependencies into their own methods. For example, you could pass in a HTTP request as a parameter to the method that extracts information from it and then returns that information. If you unit test those methods, then you would have coverage for everything other than the actual interaction between the HTTP server and client and the interaction between the server and database. Those cases can then be covered with integration tests where an environment is set up that runs test instances of the HTTP client, server, and database.
- monocularvision 8y ago> In my opinion, unit tests should only cover code that doesn't have any side-effects or interact with external dependencies. Almost sounds like functional code is the easiest to test code...
- flukus 8y agoI'd say procedural more than functional, it drives you to avoid encapsulated state and that's about it, unless of course you want to define C's level of abstraction as functional :)
- canhascodez 8y agoI would like to believe this, so let's kick it about. I hypothesize that you just get to move state around: that having a pile of perfectly functional code means that you then have to setup/inject a lot of stateful stuff in order to actually test anything, and the complexity of the code/testcode system is conserved. Is there a good way to test this? Is the whole system easier or harder to understand if the stateful bits are isolated?
- Merad 8y ago> An even bigger issue I have is the huge reliance on mocking which leads to completely brittle tests and code that can withstand no change without all hell breaking lose. In the .NET world, at least, I highly recommend the AutoFixture library. It's mainly meant for generating test data, but combined with your preferred mocking library it can auto generate mocks on the fly. For example, imagine that you're testing a class with 5 dependencies, but only one is relevant to the current test. AutoFixture will generate all the mock objects automatically for you, then let you capture the one you care about to set up its behavior for your test.
- rooam-dev 8y ago1. What does it mean to study TDD? 2. If acceptance tests are the highest level of tests, then focusing on them only may not be very efficient, mainly because they are expensive to run (see the test pyramid). If something doesn't work then most likely debugging is necessary, then it defeats the purpose a bit.