I assume you, developer or not, care about your backlog. Backlogs, like codebases, need and deserve care from everyone in the team. I’m a fan of continuous codebase improvement through constant refactoring. I love coding and I care a lot about all the codebases I work with. I understand migrations and upgrades need to happen, so why do I propose we stop creating technical stories? There’s a lot of harm in doing so. Let’s see why.
What are you paid for? I often hear “to write code”. I don’t agree with that at all since I believe we’re paid to…
The testing strategy is how you approach the automated testing of your software. Given its importance, it should be taken seriously. I’ll propose a visual way to represent it, as visual representations promote discussion, a shared understanding, and support decision making.
In a world full of technicians and politicians all having different levels of understanding, a graphic representation was often the only way to make a point; a single plummeting graphic usually aroused ten times the reaction inspired by volumes of spreadsheets. Digital Fortress
… we need to define some terminology (inspired in xUnit Test Patterns). I avoid the terms…
How do you ensure multiple apps and services of the same system play well together?
You could run end-to-end testing but it’s nearly impossible to test all the combinations. Also, the effective pinpointing of problems would be very low.
You could also test in isolation, on a per-app basis by simulating the other services' replies, but since they can evolve independently, the safety net is low as each set of tests may pass although the integration is broken.
Finally, integration testing is the typical solution because tests are run against the depended-on services. …
The techniques to test the data layer can be direct, like testing against an in-memory database (e.g. H2) or against a real database (e.g. using Docker) or indirect, like launching the backend application or testing as the end-user (UI tests). Let’s go over the direct options. The presented techniques can be applied regardless of the database technology (e.g. PostgreSQL, Redis, MongoDB).
📝 When deciding the techniques you’ll use, bear in mind the testing automation goals and where it fits in your automated testing strategy.
In order to unit test the data layer, we need to properly isolate it. Let’s imagine…
According to the hexagonal architecture, an adapter belongs to the outer layer of your app; it’s the glue between a component and the outside world, whether a database, a gateway for a REST API, your own REST API, etc. Adapters should only deal with parsing, (de)serialization, routing, error handling, and similar; they should never contain any kind of business logic.
The need to store and transmit data requires some kind of string representation which is given by serializers (object → string). Deserializers do the opposite (string → object). JSON is just a possible string representation but there are others.
@Test…
Creating constants can be a symptom of some underlying anti-patterns. But aren’t magic numbers (or strings, etc.) a bad practice? Well… don’t follow rules just because you always did it. Let’s address the typical arguments (we’ll use Kotlin in the snippets).
This is the worst reason to create constants. Tests should know nothing about the implementation other than its public APIs. Initially, a certain constant was local/private but you promoted it to global for the sake of testing. This was a bad idea because now the tests are coupled with the implementation. Tests should be seen as clients of the…
In an agile mindset, the team is responsible for the delivered software, which includes quality assurance (QA). In this scenario, QA is a role that is adopted by the team as a whole — developers should be writing automated tests. Manual testing does not scale as it’s hard to reproduce, tedious, error-prone, and not compatible with continuous delivery. However, if there are QA specialized people, they should be doing other types of work (e.g. exploratory testing), but I’ll leave that for another article.
Automating everything — from build to tests, deployment and infrastructure — is your only way forward. …
My proposal is to use Javalin (a lightweight webserver) as the test double, thereby replacing the external API (the DOC: dependent-on component). We’ll launch Javalin acting as the real API but running in localhost so that the gateway (the SUT) can’t tell the difference. We’ll confirm the validity by asserting the calls made to the test double.
📝 Java enums are a native example of value objects but they’re not adequate for an arbitrary amount of values. Typical value objects are email, password, locale, telephone number, money, IP address, URL, entity identifier, rating, file path, point, color, date, date range, distance.
Value objects are one of the building blocks of domain-driven design. Let’s explore their main characteristics (using Kotlin).
The value object is a container and carrier of an arbitrary value:
Usually, a value object holds a single value, but it can hold more. For example, an…
Test-Driven Development — TDD puts the test in the spotlight: it’s how you drive your implementation. TDD forces you to separate the “what” (test) from the “how” (implementation) so you can focus at one at a time. That’s why it can also be seen as Test Driven-Design and why the test is also known as spec (i.e. specification).
When learning TDD, you’ll hear a lot about the TDD cycle. What is that? It’s just a fancy name for the typical TDD state transitions between test/design → implement → refactor:
full-stack developer