Showing posts with label pytest. Show all posts
Showing posts with label pytest. Show all posts

Jan 12, 2020

pytest Tutorial 3 - pycharm options


  • pytest.ini
    • You can define default options like -v, -m, -x etc.,
    • [pyest]
    • addopts = -v
  • Auto-run options
    • When you make some changes, it auto-run
    • You can set interval of 2, 3, 5 secs etc.,
    • You can find this in settings gear icon in Pycharm
  • Make default pytest
    • By default it is pointed to unittest in Pycharm
    • You can change to pytest in PyCharm test configurations under
    • Tools -> Python Integrated Tools -> Default Test Runner
  • Run configuration for individual files
    • For each file, you can set -v, -m options
    • Run -> Default Configurations -> Additional Arguments
    • -v
  • Set options Globally for all instead of individual files
    • Run -> Edit Configurations -> Defaults -> Python Tests -> py.test
    • Add it here in Additional Arguments
    • This will apply to all the test files
  • Window -> Edit Tabs -> Split Vertically
    • You need to work test cases looking at your code files/Readme.
    • This will help in view both files vertically at the same time

pytest in classes

import pytest

class TestSomeStuff():
    def test_one(self):
         assert 1 == 1
   
    def test_two(self):
         assert 2 == 2

    def test_three(self):
         assert 3 == 3

class TestOtherStuff():
    def test_eleven(self):
         assert 11 == 11
   
    def test_twenty_two(self):
         assert 22 == 22

    def test_thirty_three(self):
         assert 33 == 33

We can run as all the tests a different suites as classes.
TestSomeStuff
TestOtherStuff


Jan 11, 2020

pytest Tutorial 2 -Fixtures


student.py

import json

class StudentDB:
   def __init__(self):
        self.__data = None

   def connect(self, data_file):
        with open(data_file) as json_file:
            self.__data = json.loads(data_file)

   def get_data(self, name):
        for student in self.__data['students']:
             if student['name'] == name:
                 return student

test_student.py

from student import StudentDB
import pytest

# Fixture is more like a replacement for writing both setup and teardown
# If not fixture, you can write separate functions for setup_module, teardown_module
# You need to pass db to all the unit test functions
#If you not pass scope=module, this fixture is called for each and every unit test
@pytest.fixture(scope='module')  
def db:
    print('-------Inside setup-------')
    db = StudentDB()
    db.connect('data.json')
    yield db
    print('-------Inside teardown-------')  # Since this is module level, this is called at the end of module
    db.close()

def test_scott_data(db):  # Passed from above texture
    scott_data = db.get_data('Scott')
    assert scott_data['id'] == 1
    assert scott_data['name'] == 'Scott'
    assert scott_data['result'] == 'Pass'

def test_mark_data(db):  # Passed from above texture
    scott_data = db.get_data('Mark')
    assert scott_data['id'] == 2
    assert scott_data['name'] == 'Mark'
    assert scott_data['result'] == 'Fail'



 
 


pytest Tutorial 1 - Beginner

math_func.py

def add(x,y):
   return x+y

def product(x,y)
   return x*y

test_math_func.py

from math_func import add, subtract
import pytest
import sys

# @pytest.mark.skip(reason="Do not run number add test")
# @pytest.mark.skipif(sys.version_info < (3, 3), reason="Do not run number add test") 
@pytest.mark.number
def test_add():
   assert add(3,4) == 7
   print(f'Inside test_add: {assert add(3,4)}')

@pytest.mark.parameterize('arg1, arg2, result',
[
(7, 3, 10),
('Hello', ' World', 'Hello World')
(5.5, 4.5, 10)
]
)
def test_add_parameterize(arg1, arg2, result):
   assert add(arg1, arg2) == result

@pytest.mark.number
def test_product():
   assert add(3,4) == 12
 
@pytest.mark.strings
def test_add_strings():
   assert add(3,4) == 7
   result add('Hello', ' World')
   assert result == 'Hello World'
   assert 'Hello' in result
   assert type(result) is str 

@pytest.mark.strings
def test_product_strings():
   assert product('Hello', 3) == 'HelloHelloHello'

How to run
pytest test_match_func.py
pytest test_match_func.py -v

pytest test_match_func.py::test_add

(-k Expression)
pytest -v -k "add"  # runs tests with "add" string, run both test_add & test_add_strings
pytest -v -k "add or string" # runs all 3
pytest -v -k "add and string"  # runs test_add_strings alone

(-m, --markers)
pytest -v -m number # run those marked as number
pytest -v -m strings  # run those marked as strings


(-x, --exitfirst)
pytest -v -x  # If any first failure, it totally exits and does not execute following tests

pytest -v -x --tb=no  # It won't show error stack trace

pytest -v --maxfail=2

pytest -v -s  # -s option will output any print lines

pytest -v -q  # quite mode, will not print how many test passed

pytest Tutorial 2 -Fixtures (check the other blog)




Mar 25, 2019

Python Monkey Patching

Monkey Patching:
  • Monkey Patching refers to dynamic (run-time) modifications of a class or module
  • A MonkeyPatch is a piece of Python code which extends or modifies other code at runtime
  • The unittest.mock library makes use of monkey patching to replace part of your code under test by mock objects. 
  • It provides functionality for writing clever unittests


### test1.py 
class A: 
    def func(self): 
        print("func() is being called")


### test2.py
from test1 import A

def monkey_func(self): 
     print("monkey_func() is being called...")
   
# Replacing address of "func" with "monkey_func" 
A.func = monkey_func

if __name__ == '__main__':
    obj = A()
  
    # calling function "func" whose address got replaced with "monkey_func()" 
    obj.func() 


Output:

monkey_func() is being called...