Hinzufügen Ihrer Felder zu einem Pytest-Bericht

Angesichts der Aufgabe, den HTML-Bericht bei der Arbeit mit pytest zu ändern, wodurch ich eine für meine Aufgabe geeignete Lösung gefunden habe, möchte ich sie teilen - vielleicht wird sich jemand als nützlich erweisen. * Alle Bilder sind anklickbar




Folgende Komponenten sind für den Betrieb erforderlich:
* python3 ( Linux: apt-get install python3 ) — Python
* pip3 ( Linux: apt-get install python3-pip ) — Python ( )
* pytest ( Linux: pip3 install pytest ) — framework
* pytest-html ( Linux: pip3 install pytest-html ) — pytest html-

Projektstruktur :
| - test.py (Haupttestskript)
| - conftest.py (Lokales Plug-In, in dem Hook-Skripte implementiert sind)
| - test-1.jpg (Bilddatei)
| - test-2.jpg (Datei mit Bild)

Der Inhalt von test.py:
import pytest
import base64

#  
log = { 'a':'none', 'b':'none', 'sum':'none' }
log_html = 'none'
log_img = 'none'
log_img_url = 'none'

#    
def set_global_var(a='none',b='none',sum_='none',html='none',img='none',img_url='none'):
	global log, log_html, log_img, log_img_url
	log = { 'a': a, 'b': b, 'sum': sum_ }
	log_html = html
	log_img = img
	log_img_url = img_url

# ,  ,        
@pytest.fixture(scope="function", autouse=True)
def default_global_var():
	set_global_var()

def test_default():
	'''    '''
	assert True

def test_1():
	''' '''
	#  
	a, b = 2, 2
	sum_ = a + b
	#    
	set_global_var( a = a, b = b, sum_ = sum_ )
	# 
	assert sum_ == 4

def test_2():
	''' '''
	#  
	a, b = 3, 3
	sum_ = a + b
	#  html 
	html = '''
	<p>
	  <table border="3" width="100%">
	  <tbody>
	    <tr>
	      <td bgcolor="#D3D3D3"><font color="black"><strong>a</strong></font></td>
	      <td bgcolor="#D3D3D3"><font color="black"><strong>b</strong></font></td>
	      <td bgcolor="#D3D3D3"><font color="black"><strong>sum</strong></font></td>
	    </tr>
	    <tr>
	      <td><font color="black">{0}</font></td>
	      <td><font color="black">{1}</font></td>
	      <td><font color="black">{2}</font></td>
	    </tr>
	  </tbody>
	  </table>
	  </p>
	  '''.format( a, b, sum_ )
	#    
	set_global_var( a = a, b = b, sum_ = sum_, html = html )
	# 
	assert sum_ == 6

def test_3():
	''' '''
	#  
	a, b = 4, 4
	sum_ = a + b
	#     base64
	image = open('test-1.jpg', 'rb')
	image_read = image.read()
	img = base64.encodebytes( image_read ).decode("utf-8")
	#    
	set_global_var( a = a, b = b, sum_ = sum_, img = img )
	# 
	assert sum_ == 8

def test_4():
	''' '''
	#  
	a, b = 5, 5
	sum_ = a + b
	#    url
	img_url = 'test-2.jpg'
	#    
	set_global_var( a = a, b = b, sum_ = sum_, img_url = img_url )
	# 
	assert sum_ == 10

def test_5():
	''' '''
	#  
	a, b = 5, 1
	sum_ = a + b
	#  html 
	html = '<h1> HTML-</h1>'
	#     base64
	image = open('test-1.jpg', 'rb')
	image_read = image.read()
	img = base64.encodebytes( image_read ).decode("utf-8")
	#    url
	img_url = 'test-2.jpg'
	#    
	set_global_var( a = a, b = b, sum_ = sum_, html = html, img = img, img_url = img_url )
	# 
	print ('    ...')
	assert sum_ == 6

#   
@pytest.mark.parametrize("test_a, test_b, test_sum", [(1,2,3), (2,3,5), (4,5,8)])
def test_6(test_a, test_b, test_sum):
	'''  '''
	#  
	a, b = test_a, test_b
	sum_ = a + b
	#    
	set_global_var( a = a, b = b, sum_ = sum_ )
	# 
	assert sum_ == test_sum
 


Inhalt von conftest.py:
import pytest
from py.xml import html

#   
def pytest_html_results_table_header(cells):
	cells.insert(1, html.th('description'))		#  1- 
	cells.insert(2, html.th('a'))			#  2- 
	cells.insert(3, html.th('b'))			#  3- 
	cells.insert(4, html.th('sum'))			#  4- 
	cells.pop()

def pytest_html_results_table_row(report, cells):
	cells.insert(1, html.td( report.description ))	#  1-    
	cells.insert(2, html.td( report.a ))		#  2-    
	cells.insert(3, html.td( report.b ))		#  3-    
	cells.insert(4, html.td( report.sum ))		#  4-    
	cells.pop()

# hook       
@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item, call):
	pytest_html = item.config.pluginmanager.getplugin('html')
	outcome = yield
	report = outcome.get_result()
	#     -     __doc__    
	report.description = str( item.function.__doc__ )
	report.a = str( item.module.log['a'] )
	report.b = str( item.module.log['b'] )
	report.sum = str( item.module.log['sum'] )
	#  html  image    -     
	extra = getattr(report, 'extra', [])
	if report.when == 'call':
		#  html-
		if item.module.log_html != 'none':
			extra.append(pytest_html.extras.html( item.module.log_html ))
		#  img- (    )
		if item.module.log_img != 'none':
			extra.append(pytest_html.extras.image( item.module.log_img, mime_type='image/jpg', extension='jpg' ))
		#  img-  url-
		if item.module.log_img_url != 'none':
			extra.append(pytest_html.extras.image( item.module.log_img_url ))
		report.extra = extra


Der Bericht wird in der Datei conftest.py geändert


Das Erstellen neuer Spalten erfolgt über die folgenden Funktionen: pytest_html_results_table_header (Zellen) und pytest_html_results_table_row (Bericht, Zellen) :

Der Code
#   
def pytest_html_results_table_header(cells):
	cells.insert(1, html.th('description'))		#  1- 
	cells.insert(2, html.th('a'))			#  2- 
	cells.insert(3, html.th('b'))			#  3- 
	cells.insert(4, html.th('sum'))			#  4- 
	cells.pop()

def pytest_html_results_table_row(report, cells):
	cells.insert(1, html.td( report.description ))	#  1-    
	cells.insert(2, html.td( report.a ))		#  2-    
	cells.insert(3, html.td( report.b ))		#  3-    
	cells.insert(4, html.td( report.sum ))		#  4-    
	cells.pop()


  • cells.insert ( _number , html.th ( _name )) - Einsätze eine Spalte in der Tabelle unter _number mit dem Inhalt _name

Das Abfangen der Testausführung und das Ausfüllen des Testberichts erfolgt über die Funktion hook:
def pytest_runtest_makereport (Element, Aufruf) mit dem Dekorator: @ pytest.hookimpl (hookwrapper = True) .

Der Code
# hook       
@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item, call):
	pytest_html = item.config.pluginmanager.getplugin('html')
	outcome = yield
	report = outcome.get_result()
	#     -     __doc__    
	report.description = str( item.function.__doc__ )
	report.a = str( item.module.log['a'] )
	report.b = str( item.module.log['b'] )
	report.sum = str( item.module.log['sum'] )
	#  html  image    -     
	extra = getattr(report, 'extra', [])
	if report.when == 'call':
		#  html-
		if item.module.log_html != 'none':
			extra.append(pytest_html.extras.html( item.module.log_html ))
		#  img- (    )
		if item.module.log_img != 'none':
			extra.append(pytest_html.extras.image( item.module.log_img, mime_type='image/jpg', extension='jpg' ))
		#  img-  url-
		if item.module.log_img_url != 'none':
			extra.append(pytest_html.extras.image( item.module.log_img_url ))
		report.extra = extra


Jene. Wenn das Testskript ausgeführt wird, wird die Funktion pytest_runtest_makereport (Element, Aufruf) ausgeführt , die wiederum:

  • report.description = str (item.function .__ doc__) - Der Spalte report.description wird der Wert des Attributs __doc__ der Testfunktion zugewiesen.
  • report.a = str (item.module.log ['a']) - Der Spalte report.a wird der Wert der globalen Variablen log ['a'] zugewiesen.
  • report.b = str (item.module.log ['b']) - Der Spalte report.b wird der Wert der globalen Variablen log ['b'] zugewiesen.
  • report.sum = str (item.module.log ['sum']) - Der Spalte report.sum wird der Wert der globalen Variablen log ['sum'] zugewiesen.
  • extra.append(pytest_html.extras.html( item.module.log_html )) — html-, log_html;
  • extra.append(pytest_html.extras.image( item.module.log_img, mime_type='image/jpg', extension='jpg' )) — img-, log_img;
  • extra.append(pytest_html.extras.image( item.module.log_img_url )) — img-, log_img_url.

test.py.


Parameter werden über globale Variablen und das Funktionsattribut __doc__ in den Bericht übertragen. Bei jedem Test müssen die globalen Variablen neu definiert werden.

Der Code
#  
log = { 'a':'none', 'b':'none', 'sum':'none' }
log_html = 'none'
log_img = 'none'
log_img_url = 'none'


Wir werden globalen Variablen über die Funktion Werte zuweisen:

Der Code
#    
def set_global_var(a='none',b='none',sum_='none',html='none',img='none',img_url='none'):
	global log, log_html, log_img, log_img_url
	log = { 'a': a, 'b': b, 'sum': sum_ }
	log_html = html
	log_img = img
	log_img_url = img_url


Um die Werte globaler Variablen automatisch zurückzusetzen und nicht in jedem Test zu steuern, verwenden wir Fixture.

Der Code
@pytest.fixture(scope="function", autouse=True)
def default_global_var():
	set_global_var()


Um den Test auszuführen, wechseln Sie in das Verzeichnis mit dem Testskript und führen Sie den folgenden Befehl aus:

pytest test.py -v --html=report.html --self-contained-html

Als Ergebnis des Tests wird die Datei report.html erstellt .

Testergebnis:


  1. test_default ()
    Test mit Standardparametern:

    Der Code
    def test_default():
    	'''    '''
    	assert True
    



  2. test_1 ()
    Der Test weist globalen Variablen Werte zu und überprüft das Ergebnis der Summierung.

    Der Code
    def test_1():
    	''' '''
    	#  
    	a, b = 2, 2
    	sum_ = a + b
    	#    
    	set_global_var( a = a, b = b, sum_ = sum_ )
    	# 
    	assert sum_ == 4
    



  3. test_2()

    ( html-) .

    def test_2():
    	''' '''
    	#  
    	a, b = 3, 3
    	sum_ = a + b
    	#  html 
    	html = '''
    	<p>
    	  <table border="3" width="100%">
    	  <tbody>
    	    <tr>
    	      <td bgcolor="#D3D3D3"><font color="black"><strong>a</strong></font></td>
    	      <td bgcolor="#D3D3D3"><font color="black"><strong>b</strong></font></td>
    	      <td bgcolor="#D3D3D3"><font color="black"><strong>sum</strong></font></td>
    	    </tr>
    	    <tr>
    	      <td><font color="black">{0}</font></td>
    	      <td><font color="black">{1}</font></td>
    	      <td><font color="black">{2}</font></td>
    	    </tr>
    	  </tbody>
    	  </table>
    	  </p>
    	  '''.format( a, b, sum_ )
    	#    
    	set_global_var( a = a, b = b, sum_ = sum_, html = html )
    	# 
    	assert sum_ == 6
    



  4. test_3()
    ( img-) .

    def test_3():
    	''' '''
    	#  
    	a, b = 4, 4
    	sum_ = a + b
    	#     base64
    	image = open('test-1.jpg', 'rb')
    	image_read = image.read()
    	img = base64.encodebytes( image_read ).decode("utf-8")
    	#    
    	set_global_var( a = a, b = b, sum_ = sum_, img = img )
    	# 
    	assert sum_ == 8
    




    :


  5. test_4()

    ( img-) .

    def test_4():
    	''' '''
    	#  
    	a, b = 5, 5
    	sum_ = a + b
    	#    url
    	img_url = 'test-2.jpg'
    	#    
    	set_global_var( a = a, b = b, sum_ = sum_, img_url = img_url )
    	# 
    	assert sum_ == 10
    




    :


  6. test_5()

    ( html-, img-) .

    def test_5():
    	''' '''
    	#  
    	a, b = 5, 1
    	sum_ = a + b
    	#  html 
    	html = '<h1> HTML-</h1>'
    	#     base64
    	image = open('test-1.jpg', 'rb')
    	image_read = image.read()
    	img = base64.encodebytes( image_read ).decode("utf-8")
    	#    url
    	img_url = 'test-2.jpg'
    	#    
    	set_global_var( a = a, b = b, sum_ = sum_, html = html, img = img, img_url = img_url )
    	# 
    	print ('    ...')
    	assert sum_ == 6
    



  7. test_6()

    , .

    #

    @pytest.mark.parametrize("test_a, test_b, test_sum", [(1,2,3), (2,3,5), (4,5,8)])
    def test_6(test_a, test_b, test_sum):
    	'''  '''
    	#  
    	a, b = test_a, test_b
    	sum_ = a + b
    	#    
    	set_global_var( a = a, b = b, sum_ = sum_ )
    	# 
    	assert sum_ == test_sum
    




P.S.:


In diesem Fall wurde ein Beispiel für die Übergabe von Parametern an einen Bericht über globale Variablen untersucht. Für meine Aufgabe ist dies durchaus akzeptabel. Die Verwendung globaler Variablen bringt jedoch bekannte Schwierigkeiten und Probleme mit sich. Seien Sie also vorsichtig.

Ich hoffe, dieser Artikel wird Ihnen nützlich sein.

Ein weiteres Berichtsbeispiel


All Articles