Unit testing example in python

Юнит-тесты на Python: Быстрый старт

Юнит-тестирование кода является неотъемлемой частью жизненного цикла разработки программного обеспечения. Юнит-тесты также формируют основу для проведения регрессионного тестирования, то есть они гарантируют, что система будет вести себя согласно сценарию, когда добавятся новые функциональные возможности или изменятся существующие.

В этой статье я продемонстрирую основную идею юнит-тестирования на одном классе. На практике вам придется писать множество тестовых случаев, добавлять их в тестовый набор и запускать все вместе. Управление тест-кейсами мы рассмотрим в следующей статье.

Сегодня мы сосредоточимся на тестировании бэкенда. То есть разработчик реализовал некоторый проект согласно спецификациям (например, Calculator.py), а ваша задача состоит в том, чтобы убедиться, что разработанный код действительно им соответствует (например, с помощью TestCalculator.py ).

Предположим, что вы написали класс Calculator для выполнения основных вычислительных функций: сложения, вычитания, умножения и деления.

Код для этого здесь ( Calculator.py ):

#A simple calculator class Calculator: #empty constructor def __init__(self): pass #add method - given two numbers, return the addition def add(self, x1, x2): return x1 + x2 #multiply method - given two numbers, return the #multiplication of the two def multiply(self, x1, x2): return x1 * x2 #subtract method - given two numbers, return the value #of first value minus the second def subtract(self, x1, x2): return x1 - x2 #divide method - given two numbers, return the value #of first value divided by the second def divide(self, x1, x2): if x2 != 0: return x1/x2

Теперь я хочу запустить юнит-тест, чтобы понять, что функциональность в приведенном выше классе работает, как запланировано.

Читайте также:  Onload javascript new window

Обычно Python поставляется уже с пакетом unittest . Если в вашей системе его нет, используйте pip для его установки.

Юнит-тест имеет следующую структуру:

setUp() и tearDown() – это стандартные методы, которые поставляются с фреймворком unittest (они определены в классе unittest.TestCase). В зависимости от вашего тестового случая вы можете переопределять или не переопределять два этих метода по умолчанию.

Пришло время посмотреть на код тест-кейса. Вот файл TestCalculator.py .

import unittest from Calculator import Calculator #Test cases to test Calulator methods #You always create a child class derived from unittest.TestCase class TestCalculator(unittest.TestCase): #setUp method is overridden from the parent class TestCase def setUp(self): self.calculator = Calculator() #Each test method starts with the keyword test_ def test_add(self): self.assertEqual(self.calculator.add(4,7), 11) def test_subtract(self): self.assertEqual(self.calculator.subtract(10,5), 5) def test_multiply(self): self.assertEqual(self.calculator.multiply(3,7), 21) def test_divide(self): self.assertEqual(self.calculator.divide(10,2), 5) # Executing the tests in the above test case class if __name__ == "__main__": unittest.main()

Хотя это и не обязательно, но как правило я называю тестовый класс с префиксом Test (в нашем случае TestCalculator). Ключевым требованием в этом классе является наличие надкласса unittest.TestCase .

Всякий раз, когда выполняется этот тест-кейс, сначала выполняется метод setUp(). В нашем случае мы просто создаем объект класса Calculator и сохраняем его как атрибут класса. В родительском классе есть несколько других методов по умолчанию, которые мы рассмотрим позже.

На данный момент все, что вы будете делать, это писать методы test_xxx для тестирования каждого метода в классе Calculator. Обратите внимание, что все тестовые методы начинаются с префикса test_ . Это говорит Python с помощью фреймворка unittest, что это методы тестирования.

В каждом из методов тестирования я использовал встроенный метод assertEqual , чтобы проверить, возвращают ли методы калькулятора ожидаемое значение. Если возвращаемое значение равно ожидаемому значению, то тест проходит успешно, в противном случае он завершается неудачей.

Есть множество встроенных методов assert , о которых мы будем говорить позже.

Последняя строка в приведенном выше коде просто запускает тестовый случай TestCalculator . Он выполняет каждый тестовый метод, определенный внутри класса, и выдает результат.

python TestCalculator.py -v

Вы увидите вывод, сходный со следующим:

test_add (__main__.TestCalculator) . ok test_divide (__main__.TestCalculator) . ok test_multiply (__main__.TestCalculator) . ok test_subtract (__main__.TestCalculator) . ok -------------------------------------------------------------------- Ran 4 tests in 0.000s OK

Что делать, если что-то не работает, как ожидалось? Давайте изменим ожидаемое значение test_divide с 5 на 6 (5 – правильное значение, сейчас мы посмотрим, что случится при сбое. Это не ошибка в исходном коде, а ошибка в тестовом наборе, у вас тоже могут быть ошибки в тестовых наборах, поэтому всегда проверяйте тестовые сценарии на наличие ошибок!)

import unittest from Calculator import Calculator #Test cases to test Calulator methods #You always create a child class derived from unittest.TestCase class class TestCalculator(unittest.TestCase): #setUp method overridden from the parent class TestCase def setUp(self): self.calculator = Calculator() . def test_divide(self): self.assertEqual(self.calculator.divide(10,2), 6) # Executing the tests in the above test case class if __name__ == "__main__": unittest.main()

При запуске этого тест-кейса, вы получите следующий результат:

test_add (__main__.TestCalculator) . ok test_divide (__main__.TestCalculator) . FAIL test_multiply (__main__.TestCalculator) . ok test_subtract (__main__.TestCalculator) . ok ==================================================================== FAIL: test_divide (__main__.TestCalculator) -------------------------------------------------------------------- Traceback (most recent call last): File "TestCalculator.py", line 23, in test_divide self.assertEqual(self.calculator.divide(10,2), 6) AssertionError: 5.0 != 6 -------------------------------------------------------------------- Ran 4 tests in 0.001s FAILED (failures=1)

Здесь написано, что 3 из 4 тестов прошли успешно, а один не удался. В реальном сценарии, предполагается, что ваш тестовый случай является верным, то есть таким образом он помогает определять неправильно реализованную функцию.

Источник

Python unittest — unit test example

Python unittest - unit test example

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Today we will learn about python unittest and look through python unit test example programs. In previous tutorial we learned about python zip function.

Python unittest

Python unittest module is used to test a unit of source code. Suppose, you need to test your project. You know what kind of data the function will return. After writing huge code, you need to check it whether the output is correct or not. Normally, what we do is printing the output and match it with the reference output file or check the output manually. To reduce this pain, Python has introduced unittest module. Using this module you can check the output of the function by some simple code. In this tutorial we will discuss about basic usage of Python unittest module and write some python unit test cases to test a class functions.

Python Unit Test Example Source

First of all we have to write some code to unit test them. We will have a Python class. The main purpose of the class is to store and retrieve person’s name. So, we write set_name() function to store the data and get_name() function to retrieve name from the class.

class Person: name = [] def set_name(self, user_name): self.name.append(user_name) return len(self.name) - 1 def get_name(self, user_id): if user_id >= len(self.name): return 'There is no such user' else: return self.name[user_id] if __name__ == '__main__': person = Person() print('User Abbas has been added with id ', person.set_name('Abbas')) print('User associated with id 0 is ', person.get_name(0)) 
$ python3.6 Person.py User Abbas has been added with id 0 User associated with id 0 is Abbas $ 

Python unittest structure

Now, let’s learn how to code for unit testing. An individual testcase is created by subclassing unittest.TestCase . By overriding or adding appropriate functions, we can add logic to test. The following code will be succeeded if a is equals to b.

import unittest class Testing(unittest.TestCase): def test_string(self): a = 'some' b = 'some' self.assertEqual(a, b) def test_boolean(self): a = True b = True self.assertEqual(a, b) if __name__ == '__main__': unittest.main() 

How to run python unittest module

Python unittest, python unit test example

If you’re using PyCharm IDE, you can simply press ctrl+shift+F10 to run unittest module. Otherwise you can use command prompt to run this module. For example, we named the file for unit-testing as Basic_Test.py . So the command to run python unittest will be: $python3.6 -m unittest Basic_Test.Testing If you want to see the verbose, then the command will be; $python3.6 -m unittest -v Basic_Test.Testing By using the PyCharm, we get the below output.

Python Unit Test Outcome & Basic Functions

  1. OK: If all test cases are passed, the output shows OK.
  2. Failure: If any of test cases failed and raised an AssertionError exception
  3. Error: If any exception other than AssertionError exception is raised.

There are several function under unittest module. They are listed below.

Method Checks that
assertEqual(a,b) a==b
assertNotEqual(a,b) a != b
assertTrue(x) bool(x) is True
assertFalse(x) bool(x) is False
assertIs(a,b) a is b
assertIs(a,b) a is b
assertIsNot(a, b) a is not b
assertIsNone(x) x is None
assertIsNotNone(x) x is not None
assertIn(a, b) a in b
assertNotIn(a, b) a not in b
assertIsInstance(a, b) isinstance(a, b)
assertNotIsInstance(a, b) not isinstance(a, b)

Python unit test example

Now it’s time to write unit tests for our source class Person . In this class we have implemented two function — get_name() and set_name() . Now, we will test those function using unittest . So we have designed two test cases for those two function. Have a look at the following code, you will understand it easily.

import unittest # This is the class we want to test. So, we need to import it import Person as PersonClass class Test(unittest.TestCase): """ The basic class that inherits unittest.TestCase """ person = PersonClass.Person() # instantiate the Person Class user_id = [] # variable that stores obtained user_id user_name = [] # variable that stores person name # test case function to check the Person.set_name function def test_0_set_name(self): print("Start set_name test\n") """ Any method which starts with ``test_`` will considered as a test case. """ for i in range(4): # initialize a name name = 'name' + str(i) # store the name into the list variable self.user_name.append(name) # get the user id obtained from the function user_id = self.person.set_name(name) # check if the obtained user id is null or not self.assertIsNotNone(user_id) # null user id will fail the test # store the user id to the list self.user_id.append(user_id) print("user_id length = ", len(self.user_id)) print(self.user_id) print("user_name length = ", len(self.user_name)) print(self.user_name) print("\nFinish set_name test\n") # test case function to check the Person.get_name function def test_1_get_name(self): print("\nStart get_name test\n") """ Any method that starts with ``test_`` will be considered as a test case. """ length = len(self.user_id) # total number of stored user information print("user_id length = ", length) print("user_name length = ", len(self.user_name)) for i in range(6): # if i not exceed total length then verify the returned name if i < length: # if the two name not matches it will fail the test case self.assertEqual(self.user_name[i], self.person.get_name(self.user_id[i])) else: print("Testing for get_name no user test") # if length exceeds then check the 'no such user' type message self.assertEqual('There is no such user', self.person.get_name(i)) print("\nFinish get_name test\n") if __name__ == '__main__': # begin the unittest.main() unittest.main() 

Note that the unittest module executes the test functions in the order of their name, not in the order they are defined. And since we want our set_name test to execute first, we have named our test case functions as test_0_set_name and test_1_get_name .

Python Unit Test Example Output

Below images show the output produced by our unit test program - both in normal mode and in verbose mode. Python unit test examplepython unittest tutorial

$ python3.6 -m unittest -v PersonTest.Test test_0_set_name (PersonTest.Test) . Start set_name test user_id length = 4 [0, 1, 2, 3] user_name length = 4 ['name0', 'name1', 'name2', 'name3'] Finish set_name test ok test_1_get_name (PersonTest.Test) . Start get_name test user_id length = 4 user_name length = 4 Testing for get_name no user test Testing for get_name no user test Finish get_name test ok ---------------------------------------------------------------------- Ran 2 tests in 0.000s OK $ 

That’s all about Python unittest tutorial. To learn more, read the Official Documentation. For any further query please use the comment box. 🙂

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Источник

Оцените статью