Yesterday, I finally set up integration testing for Cushion’s invoice page, using Cypress. Previous to this, I had been relying on a combination of unit tests, which focus on the individual parts more than the whole picture, and manual integration testing, which is actually me clicking through the various flows to make sure they still work—a surprisingly common form of testing.

While unit testing is automatic and part of Cushion’s CI build, I’m not automatic, so I don’t always test every flow after every commit—that would be unrealistic. I tend to only double-check the flows when I make a significant change, and with my recent work on the invoice page, you can certainly call it significant. This time, however, I wanted to do it right, so I put Cypress is place to not only automate this process for me, but also shave the time it takes down to seconds.

it("views protected invoice", () => {
  cy.visit(`/${shortId}`);
  cy.contains("passcode").should("be.visible");
  cy.get("input[name='passcode']").type(passcode);
  cy.contains("View invoice").click();
  cy.url().should("contain", `/invoices/${id}`);
});

While I ideally want the integration tests to be part of Cushion’s CI build, too, there’s a lot more work that goes into that, so I held off in the name of forward progress. Since I’m a solo dev at the end of the day, I don’t necessarily need to build my processes to work in the cloud across a team, so I do have that half-step advantage. That said, I definitely don’t want to keep the process of triggering the integration tests to be manual longterm, so I’ll be sure to bake it into CI when the dust settles with my time-sensitive work.

Right now, running the integration tests means pressing a button and watching Cypress control Chrome as it runs through all the tests. This also requires Cushion’s local servers to be up and running in order to access them from Chrome. The tricky part with CI comes into play when I’ll need to spin up the testing servers prior to the integration tests, seed the database, then tear everything down when the tests have passed. I’m not 100% sure what the best route for this is with Heroku CI, but it might be a solid reason to finally look into Github Actions.

Now that I at least have local integration tests running for the invoice page, I’ll be able to carry this knowledge and experience forward to the rest of Cushion—even the marketing site. I can test all the important flows in Cushion, like signup, onboarding, subscribing, etc. Gone are the days of writing overreaching unit tests that use mocks and spies to pretend to be integration tests, when they’re essentially only testing your mocks and spies. I feel really good about this milestone because it adds an extra level of assurance to my code. Cushion is heavily tested, but including integration tests will make it that much more solid.