3 ms·
My problem was learning how and why to do it. Most of the tutorials I've seen on the matter either test too trivially or too often. But it also says a lot abou
by aroundtown 6y ago
My problem was learning how and why to do it. Most of the tutorials I've seen on the matter either test too trivially or too often.
But it also says a lot about the places that I've worked where shipping code and carving out domain knowledge for job security was seen as more important that actually doing a good job.
- tobyhinloopen 6y agoI write tests in units of work. For example, If I need to add a contact form to a page, I’ll create a test that checks whether some form exists and matches some structure (names of fields) and I test that submitting the form performs some desired action. Usually I would replace the real mailer with a fake, test-specific mailer which has extra methods for keeping or inspecting sent mails. (There are libraries for this as well; it’s just an example). Testing the “real” mailer might never be done since it would involve checking if the mail was actually sent. In these cases I want to isolate that boundary so it is invoked as late as possible so I can use fake mailers for my tests. If the feature is mostly UI (like in this case) I usually test through the UI (using JSDOM and an HTTP client, or a virtual browser test runner like superagent). If the feature is more complex like an API or something, I like to write a barebones integration test (does this HTTP endpoint actually invoke some injected module) and then I thoroughly test the underlying module which is HTTP agnostic or represents bare minimum of HTTP state without dependencies to a real HTTP server or client. That way I can test the module without performing HTTP requests or mocking them. I usually start by writing lines like: - It returns no posts when there are no posts - It returns no deleted posts - After creating a post, posts index returns my post - Editing my posts updates my post - editing someone else’s post fails - deleting someone else’s post fails Once I’ve written the outline of my module like this, I convert them to empty tests and implement them one by one, first implementing a test, then changing the code to make the test succeed. Repeat until done. Usually I come up with more happy or unhappy cases while implementing - I instantly write a new blank test for later in these cases, adding it to the list of tests to write. I like to always have separate implementations for implementing features: one module for the business logic (which is thoroughly tested) and one for connecting it with libraries or frameworks or whatever (with minimum tests, but at least one). This is a guideline and not a requirement: sometimes a dependency to a framework or library or external service is just part of the feature so no point in keeping it separate.