I decided to change a little chronology of the documents. Although this part was supposed to be dedicated to testing frameworks, I decided to devote it to an introduction to writing unit tests: What are they really, and what tests should we be creating? By design, each unit test is a method of software testing, by doing all kinds of tests, whose job is to verify the actions of the individual elements of each program.

We use unit tests to test various methods in the classroom or at most a single object. When we say that we submit test something, we actually call a method or property, and compare the results. The values can be returned or thrown exceptions from expected results. Sometimes we expect positive results, sometimes just negative results. Negative test results are not synonymous with an ill-written application.

Note that working with the source code is very, very complicated. Mostly every implementation of new functionality requires both the creation of a new set of classes, and it is really difficult if it requires modification of other, older classes. Note that one new acting class will not spoil anything serious, but if badly modified the old class makes the whole program hang.

In addition, there might not always be a mistake. It may only occur under certain conditions. Unit testing allows us to guard against a defect in the program. In addition, well implemented unit tests allow you to create code that will defend itself in all conditions. In case of a negative test unit, we are always given the place of occurrence of the error. However, in the opposite case we have problems locating the error.

How to Write Unit Tests

This is one of the most important issues. While writing the software I often wondered what features a good unit test should have. After some time I was able to develop a list. So, you ready? Let’s get started. Here are the features of good unit tests:

  • Unit tests must be fully automated. After all, no one waits for tests to ask what to check. Unit tests must be fully automated and cannot wait for the user to give it the data.
  • Each test must be 100% reproducible. This means that for new embodiments, it must always give the same results. In a word, the test unit must be deterministic. Here is an example of a unit test badly written in Java, which is not deterministic:

  • Another characteristic of a good unit test is the ease of implementation. A unit test must be easy to write. This means that the time taken to write a good unit test should not exceed 20 – 30 minutes.
  • The test should be independent. Each unit test should be independent from the other unit tests, the operating environment, system requirements and availability of remote machines. If you write a test, we are confident that it will work in all conditions and it will not have any problems. This means that the test must be fully autonomous in the performance. In a word, a good unit test must be 100% independent. The test shown above is also not a stand-alone test.
  • A well-written unit test should remain forever, even with frequently changing functionality. A well-written unit test should always work for the method for which it was written. If the test stops working when the method does not change, but there is new functionality, it means that the test was poorly written. In other words, with the addition of new classes of functionality and performance, and regression testing, a well-written unit test should be able to defend itself.
  • Another of the rules is that anyone can run the unit test . Mostly it is believed that the unit test can only be run by the software developer or tester. Nothing could be further from the truth. The test should be able to be run by anyone, including the technical person responsible for the software, as well as the project manager, the head of the company in which we work, and the client who waits for him to deliver working software.

There is one very important thing. A unit test can never depend on a dedicated working environment or framework. The principle is that the unit test runs for each method you choose, anywhere.

  • Every good unit test must be run by pressing one button. The test should be run by pressing the button corresponding to the selected IDE Run tests. If to run a test, we need to do anything more, we should ask ourselves whether the test was really well written.
  • The test must be super-fast. A unit test must be as fast as possible. Nobody waited half an hour more to boot into a unit test. If the test runs over 5 minutes and lasts more than 15, any normal programmer will never use it and there is a risk of the emergence of software containing bugs. It is reasonable if the unit test runs for 5 seconds and lasts up to a minute.
  • Another thing, which most people forget. Naming. Each unit test must be properly named. The name must include both the name of the method, which is tested, and the name of the condition that is being tested. And that’s the first thing that we move immediately to in the examples.
  • A unit test verifies only one method for testing. Verification is not allowed for more methods, but it is permissible that the unit test checks for one and only one function.

Examples of Naming Unit Tests

I think this is a very interesting topic. Tests can be called in ways both exaggerated and too brief. The test called too sure, anyone would not like it. Even the customer finds that your comment here would be better. However, a unit test called too brief will not really benefit anyone that has it tested. A customer says yes, then he gives a lot of money for the unit tests, and does not even know which tests should be run to test the selected method.

And there is one more thing. After some time we would go back to our old code and its unit tests. We must remember that a well known unit test will certainly be better than any type of documentation. Let us now look at a well-written name of the test and consider, to which it refers. Let’s write the test sample. This is the name of:

public void createTest_whenNameIsNull_ThrowArgumentNullException () {
UTExample UTExample example = new ();
String name = null;
example.create (name);
}
public void createTest_whenNameIsEmpty_throwArgumentException () {
UTExample UTExample example = new ();
String name = string.Empty;
example.create (name);
}


So what we are creating? Let’s start from the beginning. The names of the two sections contain information about the test, which is createTest. Then there is information on what the test is testing, which is whenNameIsNull and whenNameIsEmpty. Then we have to deal with an option, which we expect, or ThrowArgumentNullException or ThrowArgumentException. And that’s called look good unit tests.

The Structure of the Code in Unit Tests

This is another very serious issue. When creating a unit test, we can not write like we like. We need to pay attention to the structure. Each test consists of the following code, namely:

  1. First Initialization – a place where we initialize all the necessary objects and methods.
  2. Second Operations – including a block of code to perform all operations.
  3. Third Verification – only in this block is the verification of test methods.

True, it seems simple. So let’s see an example of our non-deterministic test. Ready? And so we begin.

Initialization:

Want to learn more?? The InfoSec Institute Ethical Hacking course goes in-depth into the techniques used by malicious, black hat hackers with attention getting lectures and hands-on lab exercises. While these hacking skills can be used for malicious purposes, this class teaches you how to use the same hacking techniques to perform a white-hat, ethical hack, on your organization. You leave with the ability to quantitatively assess and measure threats to information assets; and discover where your organization is most vulnerable to black hat hackers. Some features of this course include:

  • Dual Certification - CEH and CPT
  • 5 days of Intensive Hands-On Labs
  • Expert Instruction
  • CTF exercises in the evening
  • Most up-to-date proprietary courseware available

Actions:

Review:

And right now you can see exactly what it looks like. True, it is not difficult? I think if none of you have any questions, we can safely move on to the next part of the article.

Depending Remove

The relationships are everything that makes our test on the external conditions. These are objects of some type, which is dependent on the performance of our test. These are all the objects with which we interact in the test to be performed. Mostly they depend on file system threads, in which we use available memory, time, and resources at our disposal.

The relationships that are needed to execute the code do not really help anything. They bother to write fully expandable software and do not allow us to write good unit tests. Think about it yourself, how can you write a good unit test, since it is dependent on time, user input, and access to remote machines or Web sites?

Or maybe they are still dependent on external classes or packages, which temporarily do not have access, but we know what they pay? How in such circumstances do we write unit tests? Now, with the help two tools. These are objects stubs and mocks.

Both types of objects are used during software development process, because the software often has more than one person working on it at a time. In terms of software, both types of these objects indicate where the program may be expanded or will be subject to change. They also show the places where the program will be included in an external class or package, or which just do not have access. But let us go one by one and soon it will all be clear.

The first objects are stubs. A stub is an empty method to be later expanded. A stub can specify a total of everything, and contain only the description of the method, and what should be found in it. Personally, I use very often stubs designing the functionality of the algorithm. Then everyone in the team knows how to expand stubs, and everyone begins to understand how the algorithm will work.

For example, for the application Runner, I am very happy to demonstrate to you what it looks like in the code and in the making of the project. Applied below, the runner is used in an existing application, because it does not like to give examples which have no reference to the surrounding world. Here is a screenshot:

And now I still want to show the structure of the classes to the left:

Remember, it’s just an example of stubs. A stub is just an empty method that does nothing and returns anything, even null.

The case of mocks is a little more complicated. A mock object is something more than a mere afterthought as a stub. It is able to do everything required of it, and much more. A mock has to see if we called all the methods and whether they were made in the correct order. If our object determines that the code you wrote does not really do all of what our “intelligent” dummy asks of it, we will send an error message.

On this principle is the difference between a mock object and a stub object. Mock objects only have one major drawback. Their formation is quite complicated for novice users. Fortunately, there are a number of frameworks that support their creation.

Summary

In this article, we focused on unit tests and good principles of their creation. Slowly we came to the end. Only we still respond with one question: why should we test applications? The first test application helps us to protect it from programming errors that may prove to be critical for its proper operation. Second, by using them, we much improve the quality of the software. Thirdly, well-written unit tests are able to replace any documentation. And fourth, they allow us to simulate the behavior of selected classes and methods.

Even at the end I would like to mention what we’ll cover in the next article. It will be 100% dedicated to creating mock objects with various frameworks. We will review all the most commonly used frameworks for creating mocks, and learn to apply them in practice. Do you prefer the examples in Eclipse or Visual Studio? Java or C #?