avatarSunil Kumar

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

4222

Abstract

n> c <span class="hljs-keyword">from</span> datetime <span class="hljs-keyword">import</span> datetime</pre></div><div id="4710"><pre><span class="hljs-keyword">import</span> pytest</pre></div><div id="a05f"><pre><span class="hljs-keyword">from</span> src.employee <span class="hljs-keyword">import</span> Employee</pre></div><div id="3501"><pre><span class="hljs-keyword">def</span> <span class="hljs-title function_">test_employee_get_name</span>(): dummy_employee = Employee(<span class="hljs-string">"Sunil"</span>, <span class="hljs-string">"Kumar"</span>, <span class="hljs-number">100000.00</span>) <span class="hljs-keyword">assert</span> dummy_employee.get_name() == <span class="hljs-string">f"<span class="hljs-subst">{dummy_employee.fname}</span> <span class="hljs-subst">{dummy_employee.lname}</span>"</span></pre></div><div id="660b"><pre><span class="hljs-attribute">def</span> test_get_salary(): <span class="hljs-attribute">dummy_employee</span> = Employee(<span class="hljs-string">"Sunil"</span>, <span class="hljs-string">"Kumar"</span>, <span class="hljs-number">100000</span>.<span class="hljs-number">00</span>) <span class="hljs-attribute">assert</span> dummy_employee.get_salary() == <span class="hljs-number">100000</span>.<span class="hljs-number">00</span></pre></div><div id="e033"><pre><span class="hljs-attribute">def</span> test_get_salary_after_tax(): <span class="hljs-attribute">dummy_employee</span> = Employee(<span class="hljs-string">"Sunil"</span>, <span class="hljs-string">"Kumar"</span>, <span class="hljs-number">100000</span>.<span class="hljs-number">00</span>) <span class="hljs-attribute">assert</span> dummy_employee.get_salary_after_tax(<span class="hljs-number">0</span>.<span class="hljs-number">25</span>) == (dummy_employee.salary - dummy_employee.salary*<span class="hljs-number">0</span>.<span class="hljs-number">25</span>)</pre></div><p id="50de"><b>let's run and see the output:</b></p><figure id="fbab"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*mGpPdI1jp7HwI71-CDGwUw.png"><figcaption></figcaption></figure><p id="d83d">Now let’s create the <b>test_employee_with_fixture.py<i> </i></b><i>to write the test for the </i><code><b>employee<i>.py</i></b></code><i>. Here y</i>ou can see we have created fixture <code>dummy_employee</code> with function scope and attached it to each test case. Here we don’t have to create an instance of an <code><b>Employee</b></code> for each test instead we are using the same fixture for each test.</p><div id="cf8b"><pre><span class="hljs-keyword">from</span> calendar <span class="hljs-keyword">import</span> c <span class="hljs-keyword">from</span> datetime <span class="hljs-keyword">import</span> datetime</pre></div><div id="6823"><pre><span class="hljs-keyword">import</span> pytest</pre></div><div id="0e60"><pre><span class="hljs-keyword">from</span> src.employee <span class="hljs-keyword">import</span> Employee</pre></div><div id="cfef"><pre><span class="hljs-comment"># Arrange</span> <span class="hljs-meta">@pytest.fixture(<span class="hljs-params">scope=<span class="hljs-string">"function"</span></span>)</span> <span class="hljs-keyword">def</span> <span class="hljs-title function_">dummy_employee</span>(): <span class="hljs-built_in">print</span>(<span class="hljs-string">"making dummy employee"</span>) <span class="hljs-keyword">return</span> Employee(<span class="hljs-string">"Sunil"</span>, <span class="hljs-string">"Kumar"</span>, <span class="hljs-number">100000.00</span>)</pre></div><div id="e77a"><pre><span class="hljs-keyword">def</span> <span class="hljs-title function_">test_employee_get_name</span>(<span class="hljs-params">dummy_employee</span>): <span class="hljs-keyword">assert</span> dummy_employee.get_name() == <span class="hljs-string">f"<span class="hljs-subst">{dummy_employee.fname}</span> <span class="hljs-subst">{dummy_employee.lname}</span>"</span></pre></div><div id="fa87"><pre><span class="hljs-keyword">def</span> <span class="hljs-title function_">test_student_add_credits</span>(<span class="hljs-params">dummy_employee</span>): <span class="hljs-keyword">assert</span> dummy_employee.get_salary() == <sp

Options

an class="hljs-number">100000.00</span></pre></div><div id="23f3"><pre><span class="hljs-attribute">def</span> test_get_salary_after_tax(dummy_employee): <span class="hljs-attribute">assert</span> dummy_employee.get_salary_after_tax(<span class="hljs-number">0</span>.<span class="hljs-number">25</span>) == (dummy_employee.salary - dummy_employee.salary*<span class="hljs-number">0</span>.<span class="hljs-number">25</span>)</pre></div><p id="76e7"><b>let’s run and see the output:</b></p><figure id="1e95"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*sfFYlRLHsUaKvZn9kE0fgQ.png"><figcaption></figcaption></figure><p id="215d"><b>Sharing fixtures across with multiple test defined in different modules</b></p><p id="4b8f">In pytest we can use <code>conftest.py</code> file to define fixtures with scope=”module” that can be used/accessed in multiple test modules in the directory.</p><p id="c3f1">lets create <b><i>conftest.py</i></b></p><div id="2ac2"><pre><span class="hljs-meta"># conftest.py</span></pre></div><div id="6b12"><pre><span class="hljs-keyword">import</span> pytest</pre></div><div id="7840"><pre><span class="hljs-keyword">from</span> src.employee <span class="hljs-keyword">import</span> Employee</pre></div><div id="e665"><pre><span class="hljs-variable">@pytest</span>.fixture(scope=<span class="hljs-string">"module"</span> ) <span class="hljs-keyword">def</span> <span class="hljs-title function_">dummy_employee</span>(): <span class="hljs-keyword">return</span> <span class="hljs-title class_">Employee</span>(<span class="hljs-string">"Sunil"</span>, <span class="hljs-string">"Kumar"</span>, <span class="hljs-number">100000.00</span>)</pre></div><div id="cd60"><pre><span class="hljs-variable">@pytest</span>.fixture(scope=<span class="hljs-string">"module"</span> ) <span class="hljs-keyword">def</span> <span class="hljs-title function_">tax</span>(): <span class="hljs-keyword">return</span> <span class="hljs-number">0.25</span></pre></div><p id="839a">Now lets defines tests in two different module files and use the fixtures defined in <b><i>conftest.py </i></b><i>file.</i></p><div id="ad6f"><pre><span class="hljs-meta"># test_employee_with_fixture1.py</span></pre></div><div id="6ab0"><pre><span class="hljs-keyword">def</span> <span class="hljs-title function_">test_employee_get_name</span>(<span class="hljs-params">dummy_employee</span>): <span class="hljs-keyword">assert</span> dummy_employee.get_name() == <span class="hljs-string">f"<span class="hljs-subst">{dummy_employee.fname}</span><span class="hljs-subst">{dummy_employee.lname}</span>"</span></pre></div><div id="56dc"><pre><span class="hljs-comment"># test_employee_with_fixture2.py</span> <span class="hljs-keyword">def</span> <span class="hljs-title function_">test_student_add_credits</span>(<span class="hljs-params">dummy_employee</span>): <span class="hljs-keyword">assert</span> dummy_employee.get_salary() == <span class="hljs-number">100000.00</span></pre></div><div id="a996"><pre>def test_get_salary_after_tax<span class="hljs-comment">(dummy_employee,tax)</span>: assert dummy_employee.get_salary_after_tax<span class="hljs-comment">(tax)</span> == <span class="hljs-comment">(dummy_employee.salary - dummy_employee.salary*tax)</span></pre></div><p id="e4b7">Screen shot from IDE</p><figure id="02c1"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*Y_0gPVrHVyQGsai34K6RHA.png"><figcaption></figcaption></figure><p id="922e"><b>let’s run and see the output:</b></p><figure id="12cf"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*4JJ3ECDTGFuw8ERg4NbvBw.png"><figcaption></figcaption></figure><p id="b16c">here we can see the test defined in different module are passed.</p><p id="214d"><b>Conclusion:</b></p><p id="ed5b"><code>pytest</code> fixtures are a generalized way to set up/tear down a test case or a test suite. We can share fixtures via <code>conftest</code>, adding multiple fixtures to tests and scoping fixtures.</p><p id="247a"><b>Reference :</b></p><p id="bed2"><a href="https://docs.pytest.org/en/7.1.x/explanation/fixtures.html">https://docs.pytest.org/en/7.1.x/explanation/fixtures.html</a></p></article></body>

Python: Unit test with Pytest- Part-5

In Part-5 we are going to see @pytest.fixture features of pytest . Fixtures define the steps and data that constitute arrange phase of a test. Fixtures are functions, which will run before each test function to which it is applied. Fixtures help us to avoid running the same code for each test, instead, we can attach a fixture to the tests and it will run and return the data to the test before running tests.

You can mark a function as a fixture by decorating it with @pytest.fixture

Example:

@pytest.fixture
def foo():
    pass

Scopes of fixtures

Fixtures can have the following types of scopes they are first requested by a test, and then destroyed based on their scope:

  • function: the default scope, the fixture is destroyed at the end of the test.
  • class: the fixture is destroyed after the last test in the class is executed.
  • module: the fixture is destroyed after the last test in the module is executed.
  • package: the fixture is destroyed after the last test in the package is executed.
  • session: the fixture is destroyed at the end of the test session.

let's see with a working example.

let’s create a sample employee.py Here we have an Employee class and its methods.

from datetime import datetime
class Employee:
def __init__(self, fname:str,lname:str,salary:float):
        self.fname = fname
        self.lname = lname
        self.salary = salary
def get_name(self):
        return f"{self.fname} {self.lname}"
def get_salary(self):
        return self.salary
    
    def get_salary_after_tax(self):
        return (self.salary - self.salary*0.25)

Now let’s create the test_employee_without_fixture.py to write the test for the employee.py. Here as you can see we are creating instance of Employee class for each test.

from calendar import c
from datetime import datetime
import pytest
from src.employee import Employee
def test_employee_get_name():
    dummy_employee = Employee("Sunil", "Kumar", 100000.00)
    assert dummy_employee.get_name() == f"{dummy_employee.fname} {dummy_employee.lname}"
def test_get_salary():
    dummy_employee = Employee("Sunil", "Kumar", 100000.00)
    assert dummy_employee.get_salary() == 100000.00
def test_get_salary_after_tax():
    dummy_employee = Employee("Sunil", "Kumar", 100000.00)
    assert dummy_employee.get_salary_after_tax(0.25) == (dummy_employee.salary - dummy_employee.salary*0.25)

let's run and see the output:

Now let’s create the test_employee_with_fixture.py to write the test for the employee.py. Here you can see we have created fixture dummy_employee with function scope and attached it to each test case. Here we don’t have to create an instance of an Employee for each test instead we are using the same fixture for each test.

from calendar import c
from datetime import datetime
import pytest
from src.employee import Employee
# Arrange
@pytest.fixture(scope="function")
def dummy_employee():
    print("making dummy employee")
    return Employee("Sunil", "Kumar", 100000.00)
def test_employee_get_name(dummy_employee):
    assert dummy_employee.get_name() == f"{dummy_employee.fname} {dummy_employee.lname}"
def test_student_add_credits(dummy_employee):
    assert dummy_employee.get_salary() == 100000.00
def test_get_salary_after_tax(dummy_employee):
    assert dummy_employee.get_salary_after_tax(0.25) == (dummy_employee.salary - dummy_employee.salary*0.25)

let’s run and see the output:

Sharing fixtures across with multiple test defined in different modules

In pytest we can use conftest.py file to define fixtures with scope=”module” that can be used/accessed in multiple test modules in the directory.

lets create conftest.py

# conftest.py
import pytest
from src.employee import Employee
@pytest.fixture(scope="module" )
def dummy_employee():
    return Employee("Sunil", "Kumar", 100000.00)
@pytest.fixture(scope="module" )
def tax():
   return 0.25

Now lets defines tests in two different module files and use the fixtures defined in conftest.py file.

# test_employee_with_fixture1.py
def test_employee_get_name(dummy_employee):
   assert dummy_employee.get_name() == f"{dummy_employee.fname}{dummy_employee.lname}"
# test_employee_with_fixture2.py
def test_student_add_credits(dummy_employee):
   assert dummy_employee.get_salary() == 100000.00
def test_get_salary_after_tax(dummy_employee,tax):
   assert dummy_employee.get_salary_after_tax(tax) == (dummy_employee.salary - dummy_employee.salary*tax)

Screen shot from IDE

let’s run and see the output:

here we can see the test defined in different module are passed.

Conclusion:

pytest fixtures are a generalized way to set up/tear down a test case or a test suite. We can share fixtures via conftest, adding multiple fixtures to tests and scoping fixtures.

Reference :

https://docs.pytest.org/en/7.1.x/explanation/fixtures.html

Pytest
Python3
Python Programming
Python
Automation Testing
Recommended from ReadMedium