My struggle as Software Engineer
Tags: develop, startup
Published: 2020-03-13 03:01:06

As Software Engineer, I spent 4 years heard and learned about QA, agile methodologies, software architecture and another topics in the college, these topics made that I loved this discipline. So, when I get my first job as backend developer, in local a *startup*, I was the only SE, the rest of my partners are Computer Science or Computer Engineer fellas.

The software methodology was a little mess, not even talk about the software architecture, I wasn't a pro with but I had some ideas to improve these processes, but when you start talking about agile methodologies and unit testing with people who love develop neural networks and embedded systems, you look like a weirdo (don't misunderstanding me, I've been learned a lot of them and I really appreciated them <3).

Well, in this post I want to write about the things I learned while I motivated to develop the bases of a *"testing"* culture. The first thing was to read, research and study a lot about testing, specifically unit testing, because they're the pillars.

At this point of my life as developer, I really believe that the motivation of implement testing (at least unit) in our projects should come from the inside, from our **"developer's soul"** just for gave a name; the soul that give us the craving to grow as developer, to create projects with high quality, the same soul that provides that feeling to experiment and learn with new things. Otherwise, you just look them like extra work, maybe like unnecessary work.

So, what I learned?

First, I found a Dijkstra's quote that blow my mind and really want to share:

*"Testing shows the presence, not the absence, of bugs"*


With this in mind, make sense when I read about *regression testing*, and what it's that? Well, is a type of software testing to confirm that a recent program or code change has not adversely affected existing features. In simple words, if you add a new feature in your project, the unit testings shows if some current feature is affected and you can track the issue.

Other thing that I want to share, it's about how to write a good test case, I've seen some developers try to optimize and create reusable code in their test cases, in some cases, making that one test case depends on to another. Please, never do that, the more autonomous is one test case, it's perfect, because you can run a single test case, for debug purposes or whatever, without concern about the rest. The thing you really need to do, it's keep in mind that isn't production code, you need to keep it simple, short, without abstractions, readable for another developers.

Here comes some tips for write good test cases:

* **The test case anatomy:** A good definition could answer three questions: *What is being tested?*, *Under what circumstances and scenario?* and *What is the expected result?*.

```javascript
describe('User service', function() {
   // What is being tested?
   describe('User singup', function() {
    // Under what circumstances and scenario?
     it(' Whitout name filed, should return a 422 HTTP Status code', async function() {
        const user = new User();

        const res = await login(user);

        // What is the expected result?
        expect(res.status).to.be.equal(422);
     })
   })
})
```

* **The AAA design patter:** When you write your test case, it's highly recommended use the AAA (**Arrange - Act - Assert**) pattern, what means:

* **A - Arrange**: All the setup code to bring the system to the scenario the test aims to simulate. This might include instantiating the unit under test constructor, adding DB records, mocking/stubbing on objects and any other preparation code.

* **A - Act**: Execute the unit under test. Usually 1 line of code.

* **A - Assert**: Ensure that the received value satisfies the expectation. Usually 1 line of code.

```javascript
describe('User service', function() {
   describe('User singup', function() {
     it(' Whitout name filed, should return a 422 HTTP Status code', async function() {
        // Arrange 
        const user = new User();

        // Act
        const res = await login(user);

        // Assert
        expect(res.status).to.be.equal(422);
     })
   })
})
```
* **The tests are documentation:** The tests should have an intuitive name that describe what it's testing. Unlike the appointment of functions in the application code, when naming a test it is preferable to use a long and explicit name that clearly describes what the test is verifying.

**Don't**

```javascript
it('Add user', async function(){
        // Arrange 
        const user = new User();

        // Act
        const res = await login(user);

        // Assert
        expect(res.status).to.be.equal(422);
})
```

**Do**

```javascript
it('Whitout name filed, should return a 422 HTTP Status code', async function(){
        // Arrange 
        const user = new User();

        // Act
        const res = await login(user);

        // Assert
        expect(res.status).to.be.equal(422);
})
```
And exists a lot of good practices and guidelines you can search, improves and apply on your existents projects, these are the cornerstone; but I  really hope you have learned something new or at least you have motivated to improve your *developer soul* ;)