API测试代码优化:移除类外层循环,实现实例变量批量赋值
Refactored Pythonic API Test Code
Alright, let's fix that clunky outer loop and make your code cleaner, more maintainable, and properly Pythonic. Defining a class inside a loop is inefficient (you’re redefining the class on every iteration) and hard to reason about. Here’s a step-by-step refactor:
Key Issues in the Original Code
- Class defined inside a
forloop (unnecessary and wasteful) - Overuse of global variables (prone to unexpected side effects and bugs)
- String-based method calls (unsafe and difficult to debug)
- Outdated Python 2 syntax (we’ll keep compatibility but note modern alternatives)
Refactored Code
import json from datetime import datetime from N import NSession from N import NArgParser from i_data_provider import iDataProvider # Load test data once, outside the class sale_list = open("sales.txt").readlines() sale_list_final = [s.rstrip() for s in sale_list] tests_list = open("tests.txt").readlines() tests_list_final = [t.rstrip() for t in tests_list] class iDeployChecks: # Replace global counters with class-level attributes (shared across instances) cnt = 0 cnt2 = 0 cnt3 = 0 cnt6 = 0 cnt11 = 0 def __init__(self, badge, environment): self.session = NSession(badge=badge, environment=environment) self.logger = self.session.logger self.sale_sgid_in_test = '' self.i_session = iDataProvider(self.session) def get_all_saleable_sales(self): if self.__class__.cnt2 == 0: self.i_session.get_sale_seller_info() self.logger.info('SUCCESS..... Get all sales api\n') self.__class__.cnt2 += 1 def get_all_sale_dashboard(self): if self.__class__.cnt6 == 0: self.i_session.get_All_sale() self.logger.info('SUCCESS..... Get all sales on dashboard api\n') self.__class__.cnt6 += 1 def get_current_user_sale_dashboard(self): if self.__class__.cnt11 == 0: self.i_session.get_current_user_sale() self.logger.info('SUCCESS..... Get current sales on dashboard api\n') self.__class__.cnt11 += 1 def get_one_sale_license(self): self.logger.info('Getting sale details from:') self.sale_sgid_list1 = [item.get('salesgid') for item in self.i_session.get_sale_seller_info()] print(" for sale " + str(self.sale_sgid_in_test)) self.logger.info('\n') self.logger.info('Get License for sale with sale sgid {}'.format(self.sale_sgid_in_test)) self.i_session.get_sale_license(self.sale_sgid_in_test) self.logger.info('SUCCESS..... Get license api\n') def get_weekly_stats_count(self): if self.__class__.cnt == 0: self.i_session.get_weekly_statistics() self.logger.info('SUCCESS..... Weekly statistics api\n') self.__class__.cnt += 1 def get_sconfig_value_count(self): self.i_session.get_sconfig_value(self.sale_sgid_in_test) self.logger.info('SUCCESS..... sconfig api\n') def run_tests(self): start = datetime.utcnow() sale_exists = True for test_name in tests_list_final: test_name = test_name.strip() # Handle special case for sale existence check if test_name == "get_all_saleable_sales": if self.__class__.cnt2 == 0: self.logger.info('Get All sales') self.get_all_saleable_sales() self.logger.info('checking if sale with GSID ' + self.sale_sgid_in_test + ' exists') sale_data = str(self.i_session.get_sale_seller_info()) if self.sale_sgid_in_test not in sale_data: print("the sale with GSID " + self.sale_sgid_in_test + " does not exist !!") end1 = datetime.utcnow() self.logger.info('i health check completed in {} seconds.'.format((end1 - start).seconds)) sale_exists = False break else: print("sale exists !!") continue # Handle license test if test_name == "get_one_sale_license": self.get_one_sale_license() continue # Handle node status test with error catching if test_name == "get_sale_node_status_value": try: self.logger.info('Get sale node status for sale sgid {}'.format(self.sale_sgid_in_test)) self.get_sale_node_status_value() except Exception as e: print(e) continue # Fallback for unknown tests try: method = getattr(self, test_name) method() except AttributeError: if self.__class__.cnt3 == 0: print('\n') print(" The testcase " + test_name + " test does not exist,please recheck test name !!") print('\n') self.__class__.cnt3 +=1 if sale_exists: end = datetime.utcnow() self.logger.info('IBDL health check completed in {} seconds.'.format((end - start).seconds)) if __name__ == '__main__': parser = NArgParser(description='i Checks') args = parser.parse_args() # Create a single class instance (no more redefining the class!) deploy_checker = iDeployChecks(args.badge, args.environment) # Iterate over sales and run tests for each for sale_sgid in sale_list_final: deploy_checker.sale_sgid_in_test = sale_sgid deploy_checker.run_tests()
What We Changed & Why
Moved Class Definition Outside the Loop
- We now create one instance of
iDeployChecksand reuse it for all sales—no more redefining the class every iteration, which saves memory and makes the code easier to follow.
- We now create one instance of
Replaced Global Variables with Class Attributes
- Counters like
cnt2are now stored as class-level attributes, so they’re shared across all instances (matching your original logic of running certain APIs only once) but avoid messy global scope.
- Counters like
Replaced String-Based Method Calls with
getattr- Instead of building method calls as strings (e.g.,
"self." + j + "()"), we usegetattr(self, test_name)to safely retrieve and call methods. This is more secure and simpler to debug.
- Instead of building method calls as strings (e.g.,
Centralized Sale SGID Handling
- We set
self.sale_sgid_in_testdirectly on the instance before running tests for each sale, so the value is available to all methods that need it without relying on external loop variables.
- We set
Cleaned Up Test Flow
- Renamed
maintorun_teststo better describe its purpose, and streamlined special-case logic for sale existence checks and error handling.
- Renamed
内容的提问来源于stack exchange,提问作者user3399495
相关产品推荐
相关产品推荐

