1+ import time
2+ import unittest
3+ import webbrowser
4+
5+ import pytest
6+ from pytest import fixture , mark
7+
8+ '''
9+ This can be used when resources need to be set up before the test cases and clean once done, like
10+ - Connect to a DB before
11+ - Launch a URL
12+ - Open a file to read/write
13+ '''
14+
15+ # The function identified by fixture can be added in arg of specific methods/functions
16+ # and will be called before and after these specific method/function
17+ # yield means that the code following will be run on the second call
18+ # the option -s must be used with pytest to have the details of strings
19+ #
20+ # @fixture()
21+ # def I_handle_DB_URL_FILE():
22+ # print(" --> connect to DB/URL/FILE", end=' ')
23+ # yield
24+ # print(" --> disconnect from DB/URL/FILE", end=' ')
25+ #
26+ # def test_function_01(I_handle_DB_URL_FILE):
27+ # print(" --> test_function_01", end=' ')
28+ # assert True
29+ #
30+ # def test_function_02(I_handle_DB_URL_FILE):
31+ # print(" --> test_function_02", end=' ')
32+ # assert True
33+ #
34+ # def test_function_03():
35+ # print(" --> test_function_03", end=' ')
36+ # assert True
37+ #
38+ #
39+ ''' pytest -v -k test_fictures.py -s
40+ test_fictures.py::test_function_01 --> connect to DB/URL/FILE --> test_function_01 PASSED --> disconnect from DB/URL/FILE
41+ test_fictures.py::test_function_02 --> connect to DB/URL/FILE --> test_function_02 PASSED --> disconnect from DB/URL/FILE
42+ test_fictures.py::test_function_03 --> test_function_03 PASSED
43+ '''
44+
45+
46+ # # But usually DB must be opened once, be used by different tests and be closed, and may need a scope to be defined
47+ # # The fixtures are created when first requested by a test, and are destroyed based on their scope:
48+ # # function: the default scope, the fixture is destroyed at the end of the test.
49+ # # class: the fixture is destroyed during teardown of the last test in the class.
50+ # # module: the fixture is destroyed during teardown of the last test in the module.
51+ # # package: the fixture is destroyed during teardown of the last test in the package.
52+ # # session: the fixture is destroyed at the end of the test session.
53+ # # Src : https://docs.pytest.org/en/6.2.x/fixture.html#fixture-scopes
54+ #
55+ # @fixture(scope="module")
56+ # def I_handle_DB_URL_FILE_V2():
57+ # print(" --> connect to DB/URL/FILE V2", end=' ')
58+ # yield
59+ # print(" --> disconnect from DB/URL/FILE V2", end=' ')
60+ #
61+ # def test_function_04(I_handle_DB_URL_FILE_V2):
62+ # print(" --> test_function_04", end=' ')
63+ # assert True
64+ #
65+ # def test_function_05(I_handle_DB_URL_FILE_V2):
66+ # print(" --> test_function_05", end=' ')
67+ # assert True
68+ #
69+ # def test_function_06():
70+ # print(" --> test_function_06", end=' ')
71+ # assert True
72+ #
73+ '''
74+ test_fictures.py::test_function_04 --> connect to DB/URL/FILE V2 --> test_function_04 PASSED
75+ test_fictures.py::test_function_05 --> test_function_05 PASSED
76+ test_fictures.py::test_function_06 --> test_function_06 PASSED --> disconnect from DB/URL/FILE V2
77+ '''
78+
79+
80+ # This can also be integrated into classes
81+ # Note : fixture functions, and method using fixture functions do not need 'self' EXCEPT if pytest.ini is used
82+ #
83+ # Althought this format can be accepted in a class not inherited from unittest.TestCase if a pytest.ini file is defined
84+ # def test_method_01(self,I_handle_DB_URL_FILE_in_class):
85+ #
86+ # It will be better to use this format for being accepted by all cases (with or without pytest.ini)
87+ # #@mark.usefixtures('I_handle_DB_URL_FILE_in_class')
88+ # def test_method_01(self):
89+ #
90+ # class repeating_calls():
91+ #
92+ # @fixture(scope='class')
93+ # def I_handle_DB_URL_FILE_in_class(self):
94+ # print(" --> connect to DB/URL/FILE in class", end=' ')
95+ # yield
96+ # print(" --> disconnect from DB/URL/FILE in class", end=' ')
97+ #
98+ # @mark.marker_name1
99+ # @mark.usefixtures('I_handle_DB_URL_FILE_in_class')
100+ # def test_method_01(self):
101+ # print(" --> test_method_01", end=' ')
102+ # assert True
103+ #
104+ # @mark.usefixtures('I_handle_DB_URL_FILE_in_class')
105+ # def test_method_02(self):
106+ # print(" --> test_method_02", end=' ')
107+ # assert True
108+ #
109+ # @mark.marker_name1
110+ # def test_method_03(self):
111+ # print(" --> test_method_03", end=' ')
112+ # assert True
113+ #
114+ #
115+ # # Without unittest.TestCase heritage
116+ # class check_01_Tests(repeating_calls): pass
117+ #
118+ #
119+ # # With unittest.TestCase heritage
120+ # class check_02_TestCase_Tests(unittest.TestCase, repeating_calls): pass
121+
122+ '''
123+ test_fictures.py::check_01_Tests::test_method_01 --> connect to DB/URL/FILE in class --> test_method_01 PASSED
124+ test_fictures.py::check_01_Tests::test_method_02 --> test_method_02 PASSED
125+ test_fictures.py::check_01_Tests::test_method_03 --> test_method_03 PASSED --> disconnect from DB/URL/FILE in class
126+ test_fictures.py::check_02_TestCase_Tests::test_method_01 --> connect to DB/URL/FILE in class --> test_method_01 PASSED
127+ test_fictures.py::check_02_TestCase_Tests::test_method_02 --> test_method_02 PASSED
128+ test_fictures.py::check_02_TestCase_Tests::test_method_03 --> test_method_03 PASSED --> disconnect from DB/URL/FILE in class
129+ '''
130+
131+ # Fictures can also be added to the conftest.py file for handling the 'package' or 'session' scope once
132+ # for all the file of the directory
133+ #
134+ # in conftest.py :
135+ # @fixture(scope='session')
136+ # def I_handle_DB_URL_FILE_in_class():
137+ # print(" --> connect to DB/URL/FILE in class", end=' ')
138+ # yield
139+ # print(" --> disconnect from DB/URL/FILE in class", end=' ')
140+ #
141+ # in test file
142+ class repeating_calls ():
143+
144+ @mark .marker_name2
145+ @mark .usefixtures ('I_handle_DB_URL_FILE_in_class' )
146+ def test_method_01 (self ):
147+ print (" --> test_method_01" , end = ' ' )
148+ assert True
149+
150+ @mark .usefixtures ('I_handle_DB_URL_FILE_in_class' )
151+ def test_method_02 (self ):
152+ print (" --> test_method_02" , end = ' ' )
153+ assert True
154+
155+ @mark .marker_name2
156+ def test_method_03 (self ):
157+ print (" --> test_method_03" , end = ' ' )
158+ assert True
159+
160+
161+ # Without unittest.TestCase heritage
162+ class check_01_Tests (repeating_calls ): pass
163+
164+
165+ # With unittest.TestCase heritage
166+ class check_02_TestCase_Tests (unittest .TestCase , repeating_calls ): pass
167+
168+ ''' With the 'session' scope, the DB is opened only once at the beginning of all tests,
169+ even if they are in differents test files, and closed at the end
170+ >>> pytest -v -s -m marker_name2
171+ test_fictures.py::check_01_Tests::test_method_01 --> connect to DB/URL/FILE in class --> test_method_01 PASSED
172+ test_fictures.py::check_01_Tests::test_method_03 --> test_method_03 PASSED
173+ test_fictures.py::check_02_TestCase_Tests::test_method_01 --> test_method_01 PASSED
174+ test_fictures.py::check_02_TestCase_Tests::test_method_03 --> test_method_03 PASSED
175+ test_marks.py::check_04_TestCase_Tests::test_method_01 PASSED
176+ test_marks.py::check_04_TestCase_Tests::test_method_02 PASSED
177+ test_marks.py::check_04_TestCase_Tests::test_method_03 SKIPPED --> disconnect from DB/URL/FILE in class
178+ '''
0 commit comments