unittest
ModuleIn Python, the unittest
module from the standard library provides a framework for unit testing.
It can be imported with import unittest
.
import unittest
unittest
In Python’s unittest framework, individual test methods can be skipped by using the skip
, skipIf
, or skipUnless
decorators, as well as the TestCase .skipTest
method.
The skipUnless
option skips the test if the condition evaluates to False
. The skipIf
option skips the test if the condition evaluates to True
.
In the code example, both skipUnless()
and skipIf()
skip the test if the operating system is not Windows.
class Tests(unittest.TestCase):@unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")def test_linux_feature(self):print("This test should only run on windows")@unittest.skipIf(not sys.platform.startswith("win"), "requires Windows")def test_other_linux_feature(self):print("This test should only run on windows")
expectedFailure
with unittest
In Python’s unittest framework, individual tests can be marked as an expected failure using the expectedFailure
decorator. With this decorator, the test will be considered successful in test results if it fails and will be marked as a failure if it passes.
In the code example, the .expectedFailure
decorator is used, and therefore, the test_something_that_fails()
test will pass if assertEqual(0,1)
fails (it indeed does fail and the test as a whole passes).
class Tests(unittest.TestCase):@unittest.expectedFailuredef test_something_that_fails(self):self.assertEqual(0, 1)
In Python, a test fixture is a mechanism for ensuring that proper test setup and teardown occur.
Test fixtures can be created by adding setUp()
and tearDown()
methods to the TestCase
child class. Text fixtures created like this run before and after each individual test.
In the code example, 'This runs before each test'
will be printed before each test in the class, and 'This runs after each test'
will be printed after each test.
class Tests(unittest.TestCase):def setUp(self):print('This runs before each test')def test_equality(self):self.assertEqual(1, 1)def test_list(self):self.assertIn(1, [1, 2, 3])def tearDown(self):print('This runs after each test')
A SyntaxError
is reported by the Python interpreter when some portion of the code is incorrect. This can include misspelled keywords, missing or too many brackets or parentheses, incorrect operators, missing or too many quotation marks, or other conditions.
age = 7 + 5 = 4File "<stdin>", line 1SyntaxError: can't assign to operator
A computer program is a collection of instructions used to perform a certain task.
A process is an abstraction used to represent a program while it is in execution.
A process typically exists in five states: New, Ready, Running, Blocked, or Finished
Context switching allows CPU cores to alternate between ready and blocked processes to best take advantage of limited computing resources.
Preemption occurs when a process is temporarily interrupted by an external scheduler to prioritize a more important task.
A process is blocked when it has to wait for a contested, limited, or slow resource, such as accessing a specific file or waiting for a network request.
The layout of a process in memory has four distinct sections:
Every process is initialized with a process control block that is required by the operating system to be able to identify and control the process.
When a process launches another process, the original process enters a parent-child relationship with the new process. This relationship facilitates the sharing of common data and signals along the hierarchy as well as the arrangement of which process may terminate first.
A thread represents the sequence of programmed instructions that are actively being executed. They share resources which allows for faster communication and context switching as well as requiring fewer system resources when compared to processes.
Multithreading is the capability for a single CPU core to execute multiple threads at once. This improves system utilization and responsiveness by more efficiently splitting up tasks
Kernel threads are threads created in kernel space using kernel code and libraries through a system call. The kernel is fully aware of these threads and can properly manage them.
User threads are threads created in user space using local code and function calls. The kernel is not aware of these threads and cannot directly control them. User threads allow for more fine-grained control by developers and are more efficient than kernel threads as they do not need to make system calls.
User threads can be mapped to kernel threads in a variety of ways: 1:1 Kernel-Level threading, N:1 User-Level threading, or M:N Hybrid threading.
assert
KeywordIn Python, the assert
keyword is used to test that a condition is met. If the condition evaluates to False
, an AssertionError
is raised with the specified error message.
The example code would produce the following output:
Traceback (most recent call last):
File "/Users/me/Desktop/exceptions.py", line 2, in <module>
assert number == 3, "number is not equal to 3!"
AssertionError: Number is not equal to 3!
number = 5assert number == 3, 'Number is not equal to 3!'
In Python, a unit test validates the behavior of a single isolated component, such as a function.
Often, a function is tested for its expected return value by giving it one or two extreme inputs and one normal use case.
unittest.TestCase
In Python, a test case is an individual test for an expected response to a given set of inputs.
In the code example, notice how test cases are created by defining a class that inherits from unittest.TestCase
. Then, tests are added by defining methods that start with the word test.
class MyTests(unittest.TestCase):def test_example(self):print('This is a test method that will pass')
main()
In Python, a test runner is a component that collects and executes tests and then provides results to the user.
Tests can be run by calling unittest.main()
in a module that has a test class derived from unittest.TestCase
.
class MyTests(unittest.TestCase):def test_example(self):print('This is a test method that will pass')unittest.main()
The example code would output:
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
assertEqual()
from unittest
In Python’s unittest framework, the assertEqual
TestCase method is used to test that two values are equal to each other.
In the code example, .assertEqual()
is checking if output
(which is add_five(1)
) is equal to 6
.
class Tests(unittest.TestCase):def test_add_five(self):output = add_five(1)self.assertEqual(output, 6)
assertIn()
from unittest
In Python’s unittest framework, the assertIn
TestCase method is used to test that a specific item is present in a container.
In the example code, .assertIn()
checks if 'red'
is present in colors
. In this case, the test will fail since 'red'
is not included in the list returned by get_rainbow_colors()
.
def get_rainbow_colors():return ['orange', 'yellow', 'green', 'blue', 'indigo', 'violet']class Tests(unittest.TestCase):def test_get_rainbow_colors(self):colors = get_rainbow_colors()self.assertIn('red', colors)
assertRaises()
from unittest
In Python’s unittest framework, the assertRaises
TestCase method is used to test that a specific exception is raised.
The assertRaises
method takes an exception type as its first argument, a function reference as its second, and an arbitrary number of arguments as the rest.
In the code example, the assertRaises()
test calls the raise_index_error()
function. If an IndexError
exception is raised, the test passes. If any other type of exception is raised or if no exception is raised, the test will fail.
class Tests(unittest.TestCase):def test_raises_index_error(self):self.assertRaises(IndexError, raise_index_error)
setUpClass()
and tearDownClass()
In Python’s unittest framework, test fixtures can be created by adding setUpClass()
and tearDownClass()
methods to the TestCase
child class. Text fixtures created like this run only once - before and after all tests in the class are executed. These methods must be decorated with the classmethod
decorator.
In the code example, 'This runs once before all tests'
will be printed once before all the tests in the class, and 'This runs once after all tests'
will be printed after all the tests.
class Tests(unittest.TestCase):@classmethoddef setUpClass(self):print('This runs once before all tests')def test_equality(self):self.assertEqual(1, 1)def test_list(self):self.assertIn(1, [1, 2, 3])@classmethoddef tearDownClass(self):print('This runs once after all tests')