Added TestRail link for test results in PRs

Signed-off-by: yevh-berdnyk <ie.berdnyk@gmail.com>
This commit is contained in:
yevh-berdnyk 2018-10-26 15:32:05 +02:00
parent 713433f443
commit c348342590
No known key found for this signature in database
GPG Key ID: E9B425FDFC4DEA9C
6 changed files with 37 additions and 26 deletions

View File

@ -11,9 +11,9 @@ from support.test_data import SingleTestData
class BaseTestReport: class BaseTestReport:
TEST_REPORT_DIR = "%s/../report" % os.path.dirname(os.path.abspath(__file__)) TEST_REPORT_DIR = "%s/../report" % os.path.dirname(os.path.abspath(__file__))
def __init__(self, sauce_username, sauce_access_key): def __init__(self):
self.sauce_username = sauce_username self.sauce_username = os.environ.get('SAUCE_USERNAME')
self.sauce_access_key = sauce_access_key self.sauce_access_key = os.environ.get('SAUCE_ACCESS_KEY')
self.init_report() self.init_report()
def init_report(self): def init_report(self):

View File

@ -1,14 +1,15 @@
import os import os
from support.base_test_report import BaseTestReport from support.base_test_report import BaseTestReport
from support.testrail_report import TestrailReport
class GithubHtmlReport(BaseTestReport): class GithubHtmlReport(BaseTestReport):
TEST_REPORT_DIR = "%s/../report" % os.path.dirname(os.path.abspath(__file__)) TEST_REPORT_DIR = "%s/../report" % os.path.dirname(os.path.abspath(__file__))
def __init__(self, sauce_username, sauce_access_key): def __init__(self):
super(GithubHtmlReport, self).__init__(sauce_username, sauce_access_key) super(GithubHtmlReport, self).__init__()
def build_html_report(self): def build_html_report(self, run_id):
tests = self.get_all_tests() tests = self.get_all_tests()
passed_tests = self.get_passed_tests() passed_tests = self.get_passed_tests()
failed_tests = self.get_failed_tests() failed_tests = self.get_failed_tests()
@ -23,14 +24,14 @@ class GithubHtmlReport(BaseTestReport):
failed_tests_html = str() failed_tests_html = str()
passed_tests_html = str() passed_tests_html = str()
if failed_tests: if failed_tests:
failed_tests_html = self.build_tests_table_html(failed_tests, failed_tests=True) failed_tests_html = self.build_tests_table_html(failed_tests, run_id, failed_tests=True)
if passed_tests: if passed_tests:
passed_tests_html = self.build_tests_table_html(passed_tests, failed_tests=False) passed_tests_html = self.build_tests_table_html(passed_tests, run_id, failed_tests=False)
return title_html + summary_html + failed_tests_html + passed_tests_html return title_html + summary_html + failed_tests_html + passed_tests_html
else: else:
return None return None
def build_tests_table_html(self, tests, failed_tests=False): def build_tests_table_html(self, tests, run_id, failed_tests=False):
tests_type = "Failed tests" if failed_tests else "Passed tests" tests_type = "Failed tests" if failed_tests else "Passed tests"
html = "<h3>%s (%d)</h3>" % (tests_type, len(tests)) html = "<h3>%s (%d)</h3>" % (tests_type, len(tests))
html += "<details>" html += "<details>"
@ -45,14 +46,18 @@ class GithubHtmlReport(BaseTestReport):
html += "<tr>" html += "<tr>"
html += "</tr>" html += "</tr>"
for i, test in enumerate(tests): for i, test in enumerate(tests):
html += self.build_test_row_html(i, test) html += self.build_test_row_html(i, test, run_id)
html += "</tbody>" html += "</tbody>"
html += "</table>" html += "</table>"
html += "</details>" html += "</details>"
return html return html
def build_test_row_html(self, index, test): def build_test_row_html(self, index, test, run_id):
html = "<tr><td><b>%d. %s</b></td></tr>" % (index + 1, test.name) test_rail_link = TestrailReport().get_test_result_link(run_id, test.testrail_case_id)
if test_rail_link:
html = "<tr><td><b>%s. <a href=\"%s\">%s</a></b></td></tr>" % (index + 1, test_rail_link, test.name)
else:
html = "<tr><td><b>%d. %s</b> (TestRail link is not found)</td></tr>" % (index + 1, test.name)
html += "<tr><td>" html += "<tr><td>"
test_steps_html = list() test_steps_html = list()
last_testrun = test.testruns[-1] last_testrun = test.testruns[-1]

View File

@ -8,8 +8,8 @@ from support.base_test_report import BaseTestReport
class TestrailReport(BaseTestReport): class TestrailReport(BaseTestReport):
def __init__(self, sauce_username, sauce_access_key): def __init__(self):
super(TestrailReport, self).__init__(sauce_username, sauce_access_key) super(TestrailReport, self).__init__()
self.password = environ.get('TESTRAIL_PASS') self.password = environ.get('TESTRAIL_PASS')
self.user = environ.get('TESTRAIL_USER') self.user = environ.get('TESTRAIL_USER')
@ -27,16 +27,15 @@ class TestrailReport(BaseTestReport):
base64.b64encode(bytes('%s:%s' % (self.user, self.password), 'utf-8')), 'ascii').strip() base64.b64encode(bytes('%s:%s' % (self.user, self.password), 'utf-8')), 'ascii').strip()
self.headers['Content-Type'] = 'application/json' self.headers['Content-Type'] = 'application/json'
self.url = 'https://ethstatus.testrail.net/index.php?/api/v2/' self.url = 'https://ethstatus.testrail.net/index.php?/'
self.api_url = self.url + 'api/v2/'
def get(self, method): def get(self, method):
raw_response = requests.get(self.url + method, headers=self.headers).text return requests.get(self.api_url + method, headers=self.headers).json()
return json.loads(raw_response)
def post(self, method, data): def post(self, method, data):
data = bytes(json.dumps(data), 'utf-8') data = bytes(json.dumps(data), 'utf-8')
raw_response = requests.post(self.url + method, data=data, headers=self.headers).text return requests.post(self.api_url + method, data=data, headers=self.headers).json()
return json.loads(raw_response)
def get_suites(self): def get_suites(self):
return self.get('get_suites/%s' % self.project_id) return self.get('get_suites/%s' % self.project_id)
@ -102,3 +101,10 @@ class TestrailReport(BaseTestReport):
'comment': '%s' % ('# Error: \n %s \n' % emoji.demojize(last_testrun.error)) + devices + test_steps if last_testrun.error 'comment': '%s' % ('# Error: \n %s \n' % emoji.demojize(last_testrun.error)) + devices + test_steps if last_testrun.error
else devices + test_steps} else devices + test_steps}
self.post(method, data=data) self.post(method, data=data)
def get_test_result_link(self, test_run_id, test_case_id):
try:
test_id = self.get('get_results_for_case/%s/%s' % (test_run_id, test_case_id))[0]['test_id']
return '%stests/view/%s' % (self.url, test_id)
except KeyError:
return None

View File

@ -112,7 +112,7 @@ class AbstractTestCase:
errors = [] errors = []
network_api = NetworkApi() network_api = NetworkApi()
github_report = GithubHtmlReport(sauce_username, sauce_access_key) github_report = GithubHtmlReport()
def verify_no_errors(self): def verify_no_errors(self):
if self.errors: if self.errors:

View File

@ -18,8 +18,8 @@ sauce_access_key = environ.get('SAUCE_ACCESS_KEY')
github_token = environ.get('GIT_HUB_TOKEN') github_token = environ.get('GIT_HUB_TOKEN')
sauce = SauceClient(sauce_username, sauce_access_key) sauce = SauceClient(sauce_username, sauce_access_key)
github_report = GithubHtmlReport(sauce_username, sauce_access_key) github_report = GithubHtmlReport()
testrail_report = TestrailReport(sauce_username, sauce_access_key) testrail_report = TestrailReport()
def pytest_addoption(parser): def pytest_addoption(parser):
@ -136,13 +136,13 @@ def pytest_configure(config):
def pytest_unconfigure(config): def pytest_unconfigure(config):
if is_master(config): if is_master(config):
if config.getoption('testrail_report'):
testrail_report.add_results()
if config.getoption('pr_number'): if config.getoption('pr_number'):
from github import Github from github import Github
repo = Github(github_token).get_user('status-im').get_repo('status-react') repo = Github(github_token).get_user('status-im').get_repo('status-react')
pull = repo.get_pull(int(config.getoption('pr_number'))) pull = repo.get_pull(int(config.getoption('pr_number')))
pull.create_issue_comment(github_report.build_html_report()) pull.create_issue_comment(github_report.build_html_report(testrail_report.run_id))
if config.getoption('testrail_report'):
testrail_report.add_results()
@pytest.mark.hookwrapper @pytest.mark.hookwrapper

View File

@ -6,7 +6,7 @@ from views.sign_in_view import SignInView
class TestLinksVerifications(SingleDeviceTestCase): class TestLinksVerifications(SingleDeviceTestCase):
@marks.testrail_id(5453) @marks.testrail_id(5453)
@marks.critical @marks.medium
def test_privacy_policy_is_accessible(self): def test_privacy_policy_is_accessible(self):
signin_view = SignInView(self.driver) signin_view = SignInView(self.driver)
no_link_found_error_msg = 'Could not find privacy policy link at' no_link_found_error_msg = 'Could not find privacy policy link at'