Unit testing is a common practice for front-end developers. According to “The State of Front End Tooling”, 52% of front-end developers have unit tested their code in 2016, a 12 percent increase over the previous year.
This article will give you an overview of unit testing and the benefits it offers, particularly in the context agile projects.
Although the examples are primarily focused on web front-end development in this article, unit testing is crucial for all types of software projects, including mobile and desktop apps, back end systems, frameworks, libraries, and frameworks. These types of projects can also benefit from the general principles described in this article.
What are Unit Tests? How do they work?
Unit testing is the process of testing individual components (or units) of your software. This is done by specifying the output values that your code should return and then verifying that they do.
A unit test is a function executed by software called a tester. You must provide the following information in this function:
- A brief explanation of what you are testing
- You can select a section of your software you wish to test (for example. A function or class?
- Test data to be used as an input or parameter in your code
- A result you would like your code to produce
Then, you will need to execute your program with the input data. Compare the results with the expected result. The test passes if both results are equal. The test fails if they aren’t equal or if there are unexpected issues (such as throwing errors),
This is how an actual test might look.
describe('hasSearchedBefore', () => it('should return true when search status is "success"', () => const state = searchStatus: status.success ; expect(hasSearchedBefore(state)).to.be.true; ); );
We are testing the function hasSearchedBefore, which takes as an argument a state object and returns a binary. Our test runner provides our test function definition as a parameter to the function it. Our assertion library includes the expect-function. An assertion library provides convenience methods to easily compare our actual result (hasSearchedBefore(state)) to our expected result (“true”).
A test suite is typically composed of many tests that test the same entity or have similar purposes. In this case, we will use the “describe-function”. As for the “hasSearchedBefore“-function, we probably want to further test the function with a state that would produce a false return value and also with no parameters whatsoever.
Sometimes, your code is dependent on events or data outside of the unit and cannot be tested completely. You want to limit your testing to your unit’s functionality and avoid side effects. To ensure that your program behaves as expected, replace external dependencies with static. This static data is known as mockdata. Many libraries are available to help you mock certain functions of your software.
What makes me want to write unit tests?
Writing unit tests is beneficial for many reasons, but the most obvious one being:
- You get a free working documentation of your code
- You can identify and fix bugs before they happen in the QA process, or at the end user
- You automatically think more about edge cases in your code.
- You can create better code that is modular, more reusable, and less dependent.
- You gain confidence in your code, which allows you to refactor with no worries
- It is much easier to work with other developers and to give the project over to someone else.
- You will sleep better at night.
- it makes you a better developer
- You don’t want anything to do with him.
What should be tested?
- Reusable components
- Libraries and open-source software in general
- API calls and the processing of response in your app
- Error Handling
- Business logic and App-Logic
- Regression tests for bugs
How do I get started with unit testing?
Step 1: Create testable code
Functions (including constructors and object methods) are the units you want to test in your code. Your functions must be pure so that they only produce side effects and operate on the parameters provided. A function that is simple to test should have as few parameters as possible (ideally, one parameter). However, a function that has no parameters can be considered pure. Each parameter that your function relies on increases the testing effort exponentially. You would have to test every possible combination of these parameters. You might consider refactoring these functions into smaller functions that are more useful and can be tested separately if you have a lot of them in your app.
External dependencies should not be a problem. Otherwise, you will have to mock every dependency that your code relies on. This can lead to a lot more effort than you want. This will allow you to create modular code that isn’t tightly coupled with other features and allows for potential dependencies to be accepted as parameters.
Step 2: Install the Tools to Test Your Code
Many tools are available to unit test web projects. They all have the same purpose. This can be overwhelming if you’re just starting to learn about the subject. However, you don’t really need much to get started. The following is our test stack.
- Node.js to test the environment (although you can also use the browser to run tests, this is more difficult to automate).
- Mocha is a test runner
- Chai is an assertion library
A few libraries can also be used to save time or provide extra comfort in certain situations. These tools are especially helpful to us.
- JSDOM is used to test DOM interaction (since Node.js does not have a DOM implementation).
- Enzyme for easy testing of React components
- Sinon for mocking asynchronous behavior, Ajax calls and function calls
You don’t usually need all of these tools, it depends on what application you are creating. You don’t have to create all of these tools manually, as there are many different boilerplates available for web projects. You can copy the functionality from an existing boilerplate to your own internal build process if you have one that you wish to keep.
You can find our front-end boilerplate, Aperto Move, and the above-mentioned testing stack on GitHub
GitHub – apertomove/move-web-starterkit: A boilerplate for web projects at Aperto Move.
Move-web-Starterkit – A boilerplate to support web projects at Aperto Move
Our boilerplate automatically recognizes any file ending *.spec.js as a unit test file. It is bundled with all other unit tests files and executed by Mocha.
You would use ES6 imports to import the test libraries and code that you need. After writing your tests, you will execute the test task “npmtest” from the command line.All tests passing makes a happy developer
Bonus: This task can be automatically executed by continuous integration environments such as Jenkins, TravisCI, Bamboo, or Bamboo. You can make sure that your code passes all unit testing before it is deployed to your live server.
What is the best time to test? Before or after the implementation?
There are many opinions about whether unit tests should be written before or after the code is implemented. Both methods have their pros and cons.
Test Driven Development (TDD) is a method that allows you to write tests before you implement your code. This will allow you to plan your code better and create a public interface before you actually start writing code.
This is contrary to the agile principle of creating tangible results using working code as soon as possible. Our Scrum team builds projects based on iterative, inter-disciplinary feedback rather than creating a plan. We want to make software that works quickly so we can get feedback as soon as possible. This involves trying out different solutions and adapting the prototype implementation to reflect early feedback. In our case, this means that the tests should be written after the team has decided on the solution. We would have to present more information to get feedback, and we might need to create tests for possible solutions that won’t make it into final products.
Your project setup will determine the best time to write unit tests. It is best to start writing your unit tests as soon as you have a solution in place. You might write your tests first if your development process relies heavily on feedback.
What does testing mean for the Agile Development Process?
To ensure that writing tests are not skipped, we have a mandatory task called “write unit test” at the start of every sprint. This is for each user story. This task is usually completed after an internal UX- or UI review of each story.
It is important to factor in the extra time required to write unit tests and estimate each user story when sprint planning meetings take place. Your velocity may be lower if you’re just starting to write unit tests, but it will soon return back to normal. Writing unit tests is a prerequisite for maintaining your velocity or improving it for larger software projects that have multiple developers.
You need to constantly refactor your code to adapt to new product requirements. You can do this easily if your code base has been thoroughly tested without worrying about breaking anything. This is particularly useful for multiple developers working on the same project. They can quickly see the unit test suite and be notified instantly if a test fails, after having changed something.
Is it worth the effort?
It is. It is. However, the time required to write tests can be made up by several other steps in the development process.
- The QA engineer is able to test faster and write fewer bug reports.
- You can implement new features quicker by spending less time fixing bugs.
- Other developers don’t have to be afraid to break things, and can jump into the project faster.
- Bugs can be located and traced in less time if they do happen
- If a test is written to cover every bug found, regressions can be eliminated
What are the best times to omit unit tests?
It is a good idea to test any software. There are some projects that unit testing might not be practical. It might not be necessary to write unit tests if you are developing a simple prototype software that will be used as a demonstration. It can be omitted to make your development process more efficient and lean.
What else can I do?
A solid foundation of unit test can make your testing process more efficient. You can monitor and continuously measure your test coverage. This is the percentage of your code that is executed within your unit test suite. This is possible with tools such as Istanbul. The code coverage value is not something to be taken too seriously. It doesn’t necessarily tell you how useful and quality your tests are.
If compatibility with browsers is important to your project, you can run unit testing automatically in different browsers using real devices either on your device farm (for example. Karma or a cloud service like Sauce Labs.
Integration tests are a useful addition to unit testing in large software projects. Although they are similar to unit tests in structure, integration tests serve a different purpose. Integration tests ensure that all parts of your software work together seamlessly, so that one module can use another’s API.
End-to-end tests are the final step in automation. These tests simulate certain user interactions with your application, including back-end interaction and business logic. End-to-end testing simulates a series user interactions using a script that controls a specific instance of your application through a browser. The script then checks whether your application responds as expected. One example is to fill out a login form automatically with invalid data, and then submit it. The script then checks if the appropriate error message appears on your web site. nightwatch.js is a good Node.js solution to end-to-end testing.
How do I get started now?
Start using tests as soon as you start your next project. It will be more difficult to implement tests for existing projects. This is because you likely haven’t written testable codes without considering testability.
This might be slow at first, but it will become much faster over time. Your first test may not have the most elegant code but that is okay. A simple test that performs poorly is better than none. You will also gain valuable experience quickly. Although unit testing may seem daunting at first glance, it is not rocket science.