How to add additional column in pytest html report - python-3.x

I need help regarding pytest html report customization. I need to print failed network request status code(By TestCase wise) in report so I did the below code. StatusCode column created successfully but not getting data in html report. also, test case-wise statuscode row does not appear in the report.
Conftest.py
#pytest.mark.optionalhook
def pytest_html_results_table_header(cells):
cells.append(html.th('Statuscode'))
Conftest.py
#pytest.mark.optionalhook
def pytest_html_results_table_header(cells):
cells.append(html.th('Statuscode'))
#pytest.mark.optionalhook
def pytest_html_result_table_row(report,cells):
cells.append(html.td(report.statuscode))
def pytest_runtest_makereport(item):
"""
Extends the PyTest Plugin to take and embed screenshot in html report, whenever test fails.
:param item:
"""
pytest_html = item.config.pluginmanager.getplugin('html')
outcome = yield
report = outcome.get_result()
setattr(report, "duration_formatter", "%H:%M:%S.%f")
extra = getattr(report, 'extra', [])
statuscode = []
if report.when == 'call' or report.when == "setup":
xfail = hasattr(report, 'wasxfail')
if (report.skipped and xfail) or (report.failed and not xfail):
file_name = report.nodeid.replace("::", "_")+".png"
_capture_screenshot(file_name)
if file_name:
html = '<div><img src="%s" alt="screenshot" style="width:304px;height:228px;" ' \
'onclick="window.open(this.src)" align="right"/></div>' % file_name
extra.append(pytest_html.extras.html(html))
for request in driver.requests:
if url in request.url and request.response.status_code >=400 and request.response.status_code <= 512:
statuscode.append(request.response.status_code)
print("*********Status codes************",statuscode)
report.statuscode=statuscode
report.extra = extra

Related

How to convert script path into JSON?

I am scraping this website : https://www.epicery.com/c/promos?gclid=CjwKCAjw97P5BRBQEiwAGflV6bGzNEAz7MTIrgelBkTR277v3lhStP5tH0wgxuLj1ytlcQAAjb-cxBoCsVwQAvD_BwE
And I am trying to retrive some info in the script path like the description.
I get the script content with the xpath and make some regex and try to load it as json:
script_path = response.xpath('/html/body/script[1]').get()
j_list = re.findall(r'\[(.*)\}\]',script_path)
j = j[0].replace("'","")
json_script = json.loads(j)
But I have this following error that I cannot handle :
raise JSONDecodeError("Extra data", s, end)
json.decoder.JSONDecodeError: Extra data: line 1 column 152446 (char 152445)
I'm not sure what do you want but this works for me:
def parse(self, response):
taxons_str = response.xpath('//script[contains(., "var taxons")]/text()').re_first(r'(?s)var taxons = (.+?)var shops')
if taxons_str:
taxons = json.loads(taxons_str)
for product in taxons:
process_your_product(product)

How to write unit_test for a function which only updates a global dict type variable - Python(pytest)

Unit-Test code for a function which does a validation operation and updates the Global dict - result_count = {'test_method':{'Total_tested': 0, 'passed': 0, 'failed': 0}
below is the function
def validate_response(testmethod, response, expected_data):
ra = response.json()
expected = expected_data['payload']
if (response.status_code == expected['response_status']) \
and (result_count[testmethod['folder']]["FAILED"] < 10):
------code logic - checks using jsondiff and re.expressions--
else:
missmatch = 'response status code missmatch'
update_result(testmethod, 'status_code', expected_data, response, missmatch, fail=True)
result_count[testmethod['folder']]['FAILED'] += 1
Need to write test for the above function. to check if the result_count is updated properly.
Regular expression library & jsondiff is also used in the mentioned function.
help required for mocking the global variable and using the same for testing.
During executing the test script below i was getting a key error for the global variable result_count. That implies that the code is unable to access the result_count.. the key error after the update - is throwing TypeError: '<=' not supported between instances of 'MagicMock' and 'int' as Error
The current issue is that the result_count is not updated when the below line code is executed.
partner_test.validate_response(test_input_mocker.method, response, expected_data)
my unit test script is as below
#patch("tests.p_test.result")
#patch("tests.p_test.result_count")
def test_validate_response_pass(result_count_mocker, monkeypatch, result_mocker, test_input_mocker):
# Build data for validate response function
response = Resp(200, {'message': 'pong'})
response_data = response.json()
expected_data = {some_test_data}
# global variable import and initialize result, result_count
from p_test import result, result_count
result_count.update(result_count_mocker.data)
result.update(result_mocker.data)
result_count_mocker.return_value = result_count_mocker.data
def update_result_mocker(*args):
mock operations here
return None
monkeypatch.setattr(partner_test, "update_result", update_result_mocker)
p_test.validate_response(test_input_mocker.method, response, expected_data)
Resp() in the test fnction is a response class created to mock the response object.
the issue can be resolved using #patch.dict(dict_name, values) below is the solution
#patch.dict(p_test.result, {dict_values })
#patch.dict(p_test.result_count, {dict_values})
def test_validate_response(monkeypatch, test_input_mocker, result_count_test):
response = Resp(200, {'message': 'pong'})
response_data = response.json()
expected_data = {----your data-----}
def update_result_mocker(*args):
# mock_operations
monkeypatch.setattr(p_test, "update_result", update_result_mocker)
p_test.validate_response(test_input_mocker.method, response, expected_data)
print(p_test.result_count)

How can I return a string from a Google BigQuery row iterator object?

My task is to write a Python script that can take results from BigQuery and email them out. I've written a code that can successfully send an email, but I am having trouble including the results of the BigQuery script in the actual email. The query results are correct, but the actual object I am returning from the query (results) always returns as a Nonetype.
For example, the email should look like this:
Hello,
You have the following issues that have been "open" for more than 7 days:
-List issues here from bigquery code
Thanks.
The code reads in contacts from a contacts.txt file, and it reads in the email message template from a message.txt file. I tried to make the bigquery object into a string, but it still results in an error.
from google.cloud import bigquery
import warnings
warnings.filterwarnings("ignore", "Your application has authenticated using end user credentials")
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from string import Template
def query_emailtest():
client = bigquery.Client(project=("analytics-merch-svcs-thd"))
query_job = client.query("""
select dept, project_name, reset, tier, project_status, IssueStatus, division, store_number, top_category,
DATE_DIFF(CURRENT_DATE(), in_review, DAY) as days_in_review
from `analytics-merch-svcs-thd.MPC.RESET_DETAILS`
where in_review IS NOT NULL
AND IssueStatus = "In Review"
AND DATE_DIFF(CURRENT_DATE(), in_review, DAY) > 7
AND ready_for_execution IS NULL
AND project_status = "Active"
AND program_name <> "Capital"
AND program_name <> "SSI - Capital"
LIMIT 50
""")
results = query_job.result() # Waits for job to complete.
return results #THIS IS A NONETYPE
def get_queryresults(results): #created new method to put query results into a for loop and store it in a variable
for i,row in enumerate(results,1):
bq_data = (i , '. ' + str(row.dept) + " " + row.project_name + ", Reset #: " + str(row.reset) + ", Store #: " + str(row.store_number) + ", " + row.IssueStatus + " for " + str(row.days_in_review)+ " days")
print (bq_data)
def get_contacts(filename):
names = []
emails = []
with open(filename, mode='r', encoding='utf-8') as contacts_file:
for a_contact in contacts_file:
names.append(a_contact.split()[0])
emails.append(a_contact.split()[1])
return names, emails
def read_template(filename):
with open(filename, 'r', encoding='utf-8') as template_file:
template_file_content = template_file.read()
return Template(template_file_content)
names, emails = get_contacts('mycontacts.txt') # read contacts
message_template = read_template('message.txt')
results = query_emailtest()
bq_results = get_queryresults(query_emailtest())
import smtplib
# set up the SMTP server
s = smtplib.SMTP(host='smtp-mail.outlook.com', port=587)
s.starttls()
s.login('email', 'password')
# For each contact, send the email:
for name, email in zip(names, emails):
msg = MIMEMultipart() # create a message
# bq_data = get_queryresults(query_emailtest())
# add in the actual person name to the message template
message = message_template.substitute(PERSON_NAME=name.title())
message = message_template.substitute(QUERY_RESULTS=bq_results) #SUBSTITUTE QUERY RESULTS IN MESSAGE TEMPLATE. This is where I am having trouble because the Row Iterator object results in Nonetype.
# setup the parameters of the message
msg['From']='email'
msg['To']='email'
msg['Subject']="This is TEST"
# body = str(get_queryresults(query_emailtest())) #get query results from method to put into message body
# add in the message body
# body = MIMEText(body)
#msg.attach(body)
msg.attach(MIMEText(message, 'plain'))
# query_emailtest()
# get_queryresults(query_emailtest())
# send the message via the server set up earlier.
s.send_message(msg)
del msg
Message template:
Dear ${PERSON_NAME},
Hope you are doing well. Please find the following alert for Issues that have been "In Review" for greater than 7 days.
${QUERY_RESULTS}
If you would like more information, please visit this link that contains a complete dashboard view of the alert.
ISE Services
The BQ result() function returns a generator, so I think you need to change your return to yield from.
I'm far from a python expert, but the following pared-down code worked for me.
from google.cloud import bigquery
import warnings
warnings.filterwarnings("ignore", "Your application has authenticated using end user credentials")
def query_emailtest():
client = bigquery.Client(project=("my_project"))
query_job = client.query("""
select field1, field2 from `my_dataset.my_table` limit 5
""")
results = query_job.result()
yield from results # NOTE THE CHANGE HERE
results = query_emailtest()
for row in results:
print(row.field1, row.field2)

How to change path displayed in pytest-html report for each test

I am using pytest-html to generate html report . but in my report complete path is displaying for each test case run.
I want only class name and test case name to be displayed.
In my conftest.py file
#pytest.mark.hookwrapper
def pytest_runtest_makereport(item, call):
pytest_html = item.config.pluginmanager.getplugin('html')
outcome = yield
report = outcome.get_result()
report.description = str(item.function.__doc__)
extra = getattr(report, 'extra', [])
if report.when == 'call':
# always add url to report
extra.append(pytest_html.extras.url('http://www.example.com/'))
xfail = hasattr(report, 'wasxfail')
if (report.skipped and xfail) or (report.failed and not xfail):
# only add additional html on failure
extra.append(pytest_html.extras.html('<div>Additional HTML</div>'))
report.extra = extra
#pytest.mark.hookwrapper
def pytest_runtest_makereport(item, call):
pytest_html = item.config.pluginmanager.getplugin('html')
outcome = yield
report = outcome.get_result()
report.description = str(item.function.__doc__)
extra = getattr(report, 'extra', [])
if report.when == 'call':
# always add url to report
extra.append(pytest_html.extras.url('http://www.example.com/'))
xfail = hasattr(report, 'wasxfail')
if (report.skipped and xfail) or (report.failed and not xfail):
# only add additional html on failure
extra.append(pytest_html.extras.html('<div>Additional HTML</div>'))
report.extra = extra
Actual Result: Complete path is displaying for each test
Expected: Only Class name and testcase name is required
You can probably use os.environ.get('PYTEST_CURRENT_TEST')

Passing input into Curl command inside python3

I'm currently working with errbot, but i'm having trouble with allowing users to enter a message to be passed along with the curl command. my plugin looks as follows:
#arg_botcmd('team_key', type=str)
#arg_botcmd('--message' , dest='message', type=str)
def oncall_page(self, msg, team_key=None, message=None):
if team_key in page_list.keys():
team_id = page_list[team_key]
data = {"message_type":"CRITICAL","state_message":"{0}".format(message)}
response = requests.post('https://www.apiurl.com/{0}'.format( team_id), data)
yield "Paging {0} ".format( team_id )
My issue is with this line:
data = {"message_type":"CRITICAL","state_message":"{0}".format(message)}
This seems to be crashing the command completely, I'm hoping users can execute one command such as "!oncall page team_name --message "
Any help would be appreciated:)
#arg_botcmd('team_key', type=str)
#arg_botcmd('--message' , dest='message', type=str)
def oncall_page(self, msg, team_key=None, message=None):
if team_key in page_list.keys():
team_id = page_list[team_key]
text = str(message)
msg_type = "critical"
data = '{"message_type":"%s", "state_message":"%s"}' % (msg_type, text)
# data = '{"message_type":"critical", "state_message":"%s"}'(text)
URL = 'https://www.apiurl.com/{0}'.format( team_id)
response = requests.post(URL , data)
This is the fix for this!

Resources