def gen2(self, flavor): """ Runs all the tests including espressos and prints out the results @return: """ testId = "GEN2" with working_directory(self.project_dir): output = check_output(["./gradlew", "connectedCheck"], shell=True, stderr=subprocess.STDOUT) flavor_list = [] flavor_exist = True if ('productFlavors' in self.gradle['android'].keys()): test_locations = '/app/build/reports/androidTests/connected/flavors' with working_directory(self.project_dir + test_locations): flavors = check_output(["ls"]).split("\n") flavor_list = [x.strip("'") for x in flavors] else: test_locations = '/app/build/reports/androidTests/connected/' flavor_exist = False #Print external Report file = 'index.html' if (flavor_exist): report_location = '/app/build/reports/androidTests/connected/flavors/' + flavor else: report_location = '/app/build/reports/androidTests/connected/' file_temp = check_output(["ls"]).split("\n") file = [x.strip("'") for x in file_temp if x != ' '][0] with working_directory(self.project_dir + report_location): soup = BeautifulSoup(open(file), 'html.parser') success_rate = soup.find(id='successRate').div.get_text() tests = soup.find(id='tests').div.get_text().encode('utf-8') failures = soup.find(id='failures').div.get_text().encode('utf-8') links = [ x.get('href') for x in soup.findAll('a') if ("tab" or ("gradle" or "html#s")) not in x.get('href') ] if (success_rate != "100%"): result = "FAILED." additional = "Success rate is : "+success_rate +". "+ failures + " of "+ tests +" tests have failed. Please check :" + \ "\n" + self.project_dir+report_location + "/index.html for more information." else: result = "SUCCEED." additional = "Success rate is : "+success_rate +". All of your tests have succeed. Please check :" + \ "\n" + self.project_dir + report_location + "/index.html for more information." return (testId, self.gen2_descp(), (result, additional))
def create_apk(self): """ :return: """ with working_directory(self.project_dir): subprocess.check_output(["./gradlew", "assembleRelease"]) self.is_apk_created = True
def b2(self): """ This test executes gradle signing Report :param project_dir: Project location :return: to be documented """ testId = "B2" signing_report = [] split_string = ":app:signingReport" with working_directory(self.project_dir): output = subprocess.check_output(["./gradlew", "signingReport"]) signing_report = output.split("\n") # parse result signing_report = signing_report[signing_report.index(split_string) + 1:] signing_report = [el for el in signing_report if "Error" in el] if len(signing_report) == 0: result = "SUCCEED." additional = "Signing task build is successful, keys are valid" else: result = "FAILED." additional = "Please check assigned keys\n" for i in signing_report: additional = additional + i + '\n' return (testId, self.b2_desc(), (result, additional))
def apk1(self, apk_folder): """ Checks the apk for the <app-name>-<flavor>-<buildType>-<versionName>.apk convention @return: """ testId = "APK1" with working_directory(self.project_dir + apk_folder): apk_names = check_output(["ls"]).split("\n") try: app_name = self.gradle['monitise']['appOptions'][0]['projectName'][ 0] except: result = "FAILED." additional = "There is no monitise section in gradle file" return (testId, self.apk1_descp(), (result, additional)) flavors = self.gradle['android']['productFlavors'][0].keys() version_name = '1.2.3' try: version_name = self.manifest['manifest']['android:versionName'] except: result = "FAILED." additional = "There is no defined android:VersionName in the AndroidManifest file" return (testId, self.apk1_descp(), (result, additional)) build_types = self.gradle['android']['buildTypes'][0].keys() # name combinations apk_results = [] if (len(flavors) == 0 or len(build_types) == 0 or version_name == ''): result = "FAILED." additional = "Check flavors, build types and version name declarations" return (testId, self.apk1_descp(), (result, additional)) else: for app in apk_names: check_app = app.split("-") if len(check_app) != 4: result = "FAILED." additional = app + " is not a valid name for the project" apk_results.append((result, additional)) else: is_valid = True additional = '' if check_app[0] != app_name: is_valid = False additional = additional + "\n==\t" + app + "'s app name is not consistent with the project" if check_app[1] not in flavors: is_valid = False additional = additional + "\n==\t" + app + "'s flavor value is not consistent with the project" if check_app[2] not in build_types: is_valid = False additional = additional + "\n==\t" + app + "'s build type is not consistent with the project" if check_app[3] != version_name: is_valid = False additional = additional + "\n==\t" + app + "'s version name is not consistent with the project" if (is_valid): result = "SUCCEED." additional = app + "'s name is valid. " apk_results.append((result, additional)) else: result = "FAILED." apk_results.append((result, additional)) return (testId, self.apk1_descp(), apk_results)
def generate_report(self, title, description): #open a file with working_directory(self.output_dir): check_output(["mkdir", "-p", "Report"]) with working_directory(self.output_dir + "/Report"): check_output(["mkdir", "-p", "js"]) check_output(["mkdir", "-p", "css"]) with working_directory(self.output_dir + "/Report/js"): f = open("report.js", "w") f.write(style.report_js) f.close() with working_directory(self.output_dir + "/Report/css"): f = open("style.css", "w") f.write(style.style_css) f.close() f = open("base-style.css", "w") f.write(style.base_style_css) f.close() # Statistics total_tests = len(self.test_results) failures = 0 for element in self.test_results: if (type(element[2]) == tuple): if (element[2][0] == "FAILED."): failures += 1 elif (type(element[2]) == list): list0 = [val1 for val1, val2 in element[2]] if "FAILED." in list0: failures += 1 successes = 0 for element in self.test_results: if (type(element[2]) == tuple): if (element[2][0] == "SUCCEED."): successes += 1 elif (type(element[2]) == list): list0 = [val1 for val1, val2 in element[2]] if "FAILED." not in list0: successes += 1 confirms = total_tests - successes - failures success_rate = int(float((successes + confirms)) / total_tests * 100) with working_directory(self.output_dir + '/Report'): file = open("report.html", "w") file.write(self.opening_string) table_setup = "<div class=\"container\">\n" \ "<h1><b>Test Summary</b></h1>\n" \ "<div id=\"summary\">\n" \ "<table>\n" \ "<tr>\n" \ "<td>\n" \ "<div class=\"summaryGroup\">\n" \ "<table>\n" \ "<tr>\n" \ "<td>\n" \ "<div class=\"infoBox\" id=\"tests\">\n" \ "<div class=\"counter\">"+str(total_tests)+"</div>\n" \ "<p>Total number of tests</p>\n" \ "</div>\n" \ "</td>\n" \ "<td>\n" \ "<div class=\"infoBox\" id=\"failures\">\n" \ "<div class=\"counter\">"+str(failures)+"</div>\n" \ "<p>Failures</p>\n" \ "</div>\n" \ "</td>\n" \ "<td>\n" \ "<div class=\"infoBox\" id=\"failures\">\n" \ "<div class=\"counter\">" + str(confirms) + "</div>\n" \ "<p>Needs Confirmation</p>\n" \ "</div>\n" \ "</td>\n" \ "<td>\n" \ "<div class=\"infoBox\" id=\"failures\">\n" \ "<div class=\"counter\">" + str(successes) + "</div>\n" \ "<p>Passed</p>\n" \ "</div>\n" \ "</td>\n" \ "</tr>\n" \ "</table></div></td><td><div class=\"infoBox failures\" id=\"successRate\">\n" \ "<div class=\"percent\">"+str(success_rate)+"%</div>\n" \ "<p>successful</p>\n" \ "</div>\n" \ "</td>\n" \ "</tr>\n" \ "</table>\n" \ "</div>"\ "<h1><b>" + title +"</b></h1>\n" \ "<p>" + description +"</p>\n" \ "<div class=\"table\" >\n" \ "<table class=\"table table-hover table-cond\" border=\"4px\">\n" \ "<thead>\n" \ "<tr>\n" \ "<th>Test Id</th>\n" \ "<th>Description</th>\n" \ "<th>Result</th>\n" \ "<th>Additional Information</th>\n" \ "</tr>\n" \ "</thead>\n" file.write(table_setup) file.write("<tbody>\n") for elements in self.test_results: if type(elements[2]) == list: is_succeed = False is_failed = False for element in elements[2]: if element[0] == "SUCCEED.": is_succeed = True elif element[0] == "FAILED.": is_failed = True if (is_succeed and not (is_failed)): file.write("<tr class=\"success\">") elif (is_succeed and is_failed): file.write("<tr class=\"warning\">") elif (not (is_succeed) and is_failed): file.write("<tr class=\"danger\">") elif "FAILED." in elements[2]: file.write("<tr class=\"danger\">") elif "CONFIRM:" in elements[2]: file.write("<tr class=\"info\">") elif "SUCCEED." in elements[2]: file.write("<tr class=\"success\">") for index in range(len(elements)): if type(elements[index]) == str: file.write("<td>\n") if index == 0: file.write("<b>" + elements[index].replace("\n", "<br />") + "</b>\n") else: file.write(elements[index]) file.write("</td>\n") elif type(elements[index]) == tuple: file.write("<td>\n") file.write("<b>" + elements[index][0].replace("\n", "<br />") + "</b>\n") file.write("</td>\n") file.write("<td>\n") file.write(elements[index][1].replace("\n", "<br />\n")) file.write("</td>\n") elif type(elements[index]) == list: file.write("<td>\n") file.write("<b>\n") for sub_sub in elements[index]: file.write(sub_sub[0].replace("\n", "<br />") + "<br />\n") file.write("</b>\n") file.write("</td>\n") file.write("<td>\n") for sub_sub in elements[index]: file.write(sub_sub[1].replace("\n", "<br />") + "<br />\n") file.write("</td>\n") file.write("</tr>\n") file.write("</tbody>\n</table>\n</div>\n</div>\n") file.write(self.closing_string) file.close()
def __init__(self, gradle_dir): with working_directory(gradle_dir): self.file = open("build.gradle", "r") def handle_token(type, token, (srow, scol), (erow, ecol), line): self.tokens_initial.append((tokenize.tok_name[type], repr(token).strip("\"\'")))
def __init__(self, gradle_dir): with working_directory(gradle_dir): self.file = open("build.gradle", "r")
def gen4(self, apk_location, sdk_location): """ runs aapt command and verifies permissions, locales and densities supported @return: """ testId = "GEN4" res_add = [] with working_directory(sdk_location): output = check_output( ["./aapt", "d", "badging", self.project_dir + apk_location]) # information extraction list = output.split("\n") permission_aapt = [ re.search("\'[\s\S]+\'", x).group(0).strip("'") for x in list if "permission" in x ] permission_annotate = [ re.search("^[\s\S]+:", x).group(0).strip(":") for x in list if "permission" in x ] permission_manifest = [ x["@android:name"] for x in self.manifest['manifest']['uses-permission'] ] densitiy_info = [x for x in list if "densities" in x] densities_supported = map(lambda x: x.strip("'"), densitiy_info[0].split(" ")[1:]) any_density = [x for x in list if "supports-any-density" in x] locales = [x for x in list if "locales" in x] locales_supported = map(lambda x: x.strip("'"), locales[0].split(" ")[1:]) try: locales_gradle = self.gradle['android']['defaultConfig'][0][ 'resConfigs'][0] except: pass # Verify permissions aapt_length = len(permission_aapt) manifest_length = len(permission_manifest) if (aapt_length != manifest_length): result = "FAILED." len_long = permission_aapt if aapt_length > manifest_length else permission_manifest len_short = permission_manifest if len_long == permission_aapt else permission_aapt additional = "The number of permissions in manifest and aapt result are different." \ "" differences = '' for i in len_long: if i < len(len_short): if (len_long[i] != len_short[i]): differences = differences + permission_annotate[ i] + "->" res_add.append((result, additional)) # Verify Densities if "true" in any_density[0]: result = "SUCCEED." additional = "Application supports all densities. Here are the defined ones: " \ + " ".join(densities_supported) res_add.append((result, additional)) else: result = "WARNING." additional = "Support any density option is false. Here are the defined densities: " \ + " ".join(densities_supported) res_add.append(result, additional) # Verify Locales locale_check = True if (len(locales_gradle) == 0 or len(locales_supported) == 0): result = "FAILED." additional = "Your locale definitions are empty. Check your Project" res_add.append((result, additional)) for locale in locales_supported: if locale not in locales_gradle: locale_check = False if (locale_check): result = "SUCCEED." additional = "Your locale definitions are consistent" res_add.append((result, additional)) else: result = "FAILED." additional = "Your locale definitions are inconsistent. Check your Project" res_add.append((result, additional)) return (testId, self.gen4_descp(), res_add)