selenium POM基于unittest 自动化测试

selenium POM基于unittest 测试框架说明
 
1、自动化框架
由一个或多个自动化测试基础模块、自动化测试管理模块、自动化测试统计模块等组成的工具集合。
 
2、根据不同的分类可以分为
按框架的定义分:基础功能测试框架、管理执行框架
按不同的测试类型来分:功能自动化测试框架、性能自动化测试框架
按测试阶段分:单元自动化测试框架、接口自动化测试框架、系统自动化测试框架
按组成结构分:单一自动化测试框架、综合自动化测试框架
按部署方式分:单机自动化测试框架、分布式自动化测试框架
 
3、自动化框架的原则:
测试框架脚本与业务、数据分离
测试框架与被测试应用程序独立
测试框架脚本应易于扩展、维护
测试脚本所使用语言应该与框架独立
测试框架不应该让框架的复杂性影响到测试人员
 
4、进入主题介绍selenium POM基于unittest 测试框架说明
1.第三方包功能重新封装
2.界面元素与测试内部对象名分离
3.脚本与数据分离
4.通过Jenkins持续从svn中获取测试用例,进行持续化集成
 
5、总体目录结构以及说明
1.1 conf 目录: 存放的是配置文件
1.2 data目录:存放Excel的文件,参数多少可以使用Excel参数存放和读取参数以及对于的值
1.3 public包:存放的封装的工具类
1.4 report :测试报告
1.5 testcase : 存放的是测试用例
1.6 run_all.py : 运行入口
 
2、各模块介绍:
2.1 配置文件
如果我们程序没有任何配置文件时,这样的程序对外是全封闭的,一旦程序需要修改一些参数必须要修改程序代码本身并重新编译,这样很不好,所以要用配置文件,让程序在不同的操作系统以及环境中根据本地实际情况正常运行;配置文件有很多如INI配置文件,XML配置文件等。
 
conf 目录: 存放的是配置文件 conf,ini
config.ini
 1 [log]
 2 # 日志路径
 3 log_path = C:\Users\Administrator\PycharmProjects\auto_ui_test\report\log\
 4 
 5 [image]
 6 # 截图文件路径
 7 img_path = C:\Users\Administrator\PycharmProjects\auto_ui_test\report\image\
 8 
 9 [report]
10 # 测试报告路径
11 report_path = C:\Users\Administrator\PycharmProjects\auto_ui_test\report\
12 
13 [test_case]
14 test_case_path = C:\Users\Administrator\PycharmProjects\auto_ui_test\testcase
15 
16 [data]
17 # 测试数据路径
18 data_path = C:\Users\Administrator\PycharmProjects\auto_ui_test\data
View Code

 

2.2 数据文件
当我们的测试用例中需要填写很多参数时,为了方便修改以及读取,参数化就应运而生。使用参数,当我们后期维护测试用例时,可以减少必要的冗余,减少后期的维护量。
 
data目录:存放Excel的文件,参数多少可以使用Excel参数存放和读取参数以及对于的值
这个结合本地的项目自行选择
 
2.3 工具类的封装
首先要说明POM(PageObjectModel)的好处
POM是Selenium中的一种测试设计模式,主要是将每一个页面设计为一个Class,其中包含页面中需要测试的元素(按钮,输入框,标题 等),这样在Selenium测试页面中可以通过调用页面类来获取页面元素,这样巧妙的避免了当页面元素id或者位置变化时,需要改测试页面代码的情况。 当页面元素id变化时,只需要更改测试页Class中页面的属性即可。
 
base:
存放页面上的元素以及业务流程,业务流程比较复杂也可以单独重新封装业务流程,根据本地项目自行选择
login_page.py
login_page.py
 1 from public.common.base_obj import base_frame
 2 
 3 
 4 # 页面对象(PO) 登录页面
 5 class LoginPage(base_frame):
 6 
 7     
 8     username_loc = ('id=userName')
 9     passwd_loc = ('id=password')
10     btn_loc = ('id=login-btn')
11     error_text_loc = ('class=font-16')
12 
13 
14     def username(self, text):
15         self.send_keys(self.username_loc, text)
16 
17     def password(self, text):
18         self.send_keys(self.passwd_loc, text)
19 
20     def click_login_btn(self):
21         self.click(self.btn_loc)
22 
23     def error_text(self):
24         self.get_text(self.error_text_loc)
25 
26     def pro(self, username, passwd):
27         self.username(username)
28         self.password(passwd)
29         self.click_login_btn()
View Code

 

 
common:
存放的工具类, 读取配置,获取Excel,发送邮件,读取数据库,封装的selenium的api等
base_obj.py selenium的二次封装
base_obj.py
  1 # coding=utf-8
  2 
  3 import time,os
  4 from selenium import webdriver
  5 from selenium.webdriver.common.action_chains import ActionChains
  6 from selenium.common.exceptions import  TimeoutException
  7 from selenium.webdriver.support import expected_conditions as EC
  8 from selenium.webdriver.support.ui import WebDriverWait
  9 from selenium.webdriver.common.by import By
 10 
 11 BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
 12 conf_path = BASE_DIR + '/config/config.ini'
 13 conf_path = conf_path.replace('/', '\\')
 14 
 15 from public.common.get_log import Log
 16 from public.common.get_config import r_config
 17 from selenium.webdriver.common.keys import Keys
 18 
 19 img_path = r_config(conf_path, 'image', 'img_path')
 20 log_path = r_config(conf_path, 'log', 'log_path')
 21 success = "SUCCESS   "
 22 fail = "FAIL   "
 23 logger = Log(log_path)
 24 
 25 class base_frame(object):
 26 
 27 
 28     def __init__(self, driver, base_url="http://www.baidu.com"):
 29         self.driver = driver
 30         self.base_url = base_url
 31         self.timeout = 30
 32 
 33     def my_print(self, msg):
 34         logger.info(msg)
 35 
 36     def open(self, url):
 37 
 38         t1 = time.time()
 39         try:
 40             self.driver.get(url)
 41             self.my_print("{0} Navigated to {1}, Spend {2} seconds".format(success, url, time.time() - t1))
 42         except Exception:
 43             self.my_print("{0} Unable to load {1}, Spend {2} seconds".format(fail, url, time.time() - t1))
 44             raise
 45 
 46     def max_window(self):
 47 
 48         t1 = time.time()
 49         self.driver.maximize_window()
 50         self.my_print("{0} Set browser window maximized, Spend {1} seconds".format(success, time.time() - t1))
 51 
 52     def set_window(self, wide, high):
 53 
 54         t1 = time.time()
 55         self.driver.set_window_size(wide, high)
 56         self.my_print("{0} Set browser window wide: {1},high: {2}, Spend {3} seconds".format(success,
 57                                                                                              wide, high,
 58                                                                                              time.time() - t1))
 59 
 60     def wait(self, secs):
 61 
 62         t1 = time.time()
 63         self.driver.implicitly_wait(secs)
 64         self.my_print("{0} Set wait all element display in {1} seconds, Spend {2} seconds".format(success,
 65                                                                                                   secs,
 66                                                                                                   time.time() - t1))
 67 
 68     def find_element(self, element):
 69 
 70         if "=" not in element:
 71             raise NameError("Positioning syntax errors, lack of '='")
 72 
 73         by = element[:element.index("=")]
 74         value = element[element.index("=")+1:]
 75 
 76         if by == "id":
 77             return self.driver.find_element_by_id(value)
 78         elif by == "name":
 79             return self.driver.find_element_by_name(value)
 80         elif by == "class":
 81             return self.driver.find_element_by_class_name(value)
 82         elif by == "text":
 83             return self.driver.find_element_by_link_text(value)
 84         elif by == "text_part":
 85             return self.driver.find_element_by_partial_link_text(value)
 86         elif by == "xpath":
 87             return self.driver.find_element_by_xpath(value)
 88         elif by == "css":
 89             return self.driver.find_element_by_css_selector(value)
 90         else:
 91             raise NameError("Please enter the correct targeting elements,'id','name','class','text','xpath','css'.")
 92 
 93     def wait_element(self, element, seconds=5):
 94 
 95 
 96         if "=" not in element:
 97             raise NameError("Positioning syntax errors, lack of '='")
 98 
 99         by = element[:element.index("=")]
100         value = element[element.index("=")+1:]
101         messages = 'Element: {0} not found in {1} seconds.'.format(element, seconds)
102 
103         if by == "id":
104             WebDriverWait(self.driver, seconds, 1).until(EC.presence_of_element_located((By.ID, value)), messages)
105         elif by == "name":
106             WebDriverWait(self.driver, seconds, 1).until(EC.presence_of_element_located((By.NAME, value)), messages)
107         elif by == "class":
108             WebDriverWait(self.driver, seconds, 1).until(EC.presence_of_element_located((By.CLASS_NAME, value)),
109                                                          messages)
110         elif by == "text":
111             WebDriverWait(self.driver, seconds, 1).until(EC.presence_of_element_located((By.LINK_TEXT, value)),
112                                                          messages)
113         elif by == "xpath":
114             WebDriverWait(self.driver, seconds, 1).until(EC.presence_of_element_located((By.XPATH, value)), messages)
115         elif by == "css":
116             WebDriverWait(self.driver, seconds, 1).until(EC.presence_of_element_located((By.CSS_SELECTOR, value)),
117                                                          messages)
118         else:
119             raise NameError("Please enter the correct targeting elements,'id','name','class','text','xpaht','css'.")
120 
121     def send_keys(self, element, text):
122 
123         t1 = time.time()
124         try:
125             self.wait_element(element)
126             self.find_element(element).clear()
127             self.find_element(element).send_keys(text)
128             self.my_print("{0} Typed element: <{1}> content: {2}, Spend {3} seconds".format(success,
129                                                                                             element, text,
130                                                                                             time.time() - t1))
131         except Exception:
132             self.my_print("{0} Unable to type element: <{1}> content: {2}, Spend {3} seconds".format(fail,
133                                                                                                      element, text,
134                                                                                                      time.time() - t1))
135             raise
136 
137     def send_keys_and_enter(self, element, text, secs=0.5):
138 
139         t1 = time.time()
140         try:
141             self.wait_element(element)
142             self.find_element(element).clear()
143             self.find_element(element).send_keys(text)
144             time.sleep(secs)
145             self.find_element(element).send_keys(Keys.ENTER)
146             self.my_print(
147                 "{0} Element <{1}> type content: {2},and sleep {3} seconds,input ENTER key, Spend {4} seconds".format(
148                     success, element, text, secs, time.time() - t1))
149         except Exception:
150             self.my_print(
151                 "{0} Unable element <{1}> type content: {2},and sleep {3} seconds,input ENTER key, Spend {4} seconds".
152                     format(fail, element, text, secs, time.time() - t1))
153             raise
154 
155     def click(self, element):
156 
157         t1 = time.time()
158         try:
159             self.wait_element(element)
160             self.find_element(element).click()
161             self.my_print("{0} Clicked element: <{1}>, Spend {2} seconds".format(success, element, time.time() - t1))
162         except Exception:
163             self.my_print(
164                 "{0} Unable to click element: <{1}>, Spend {2} seconds".format(fail, element, time.time() - t1))
165             raise
166 
167     def right_click(self, element):
168 
169         t1 = time.time()
170         try:
171             self.wait_element(element)
172             ActionChains(self.driver).context_click(self.find_element(element)).perform()
173             self.my_print(
174                 "{0} Right click element: <{1}>, Spend {2} seconds".format(success, element, time.time() - t1))
175         except Exception:
176             self.my_print(
177                 "{0} Unable to right click element: <{1}>, Spend {2} seconds".format(fail, element, time.time() - t1))
178             raise
179 
180     def move_to_element(self, element):
181 
182         t1 = time.time()
183         try:
184             self.wait_element(element)
185             ActionChains(self.driver).move_to_element(self.find_element(element)).perform()
186             self.my_print("{0} Move to element: <{1}>, Spend {2} seconds".format(success, element, time.time() - t1))
187         except Exception:
188             self.my_print(
189                 "{0} unable move to element: <{1}>, Spend {2} seconds".format(fail, element, time.time() - t1))
190         raise
191 
192     def double_click(self, element):
193 
194         t1 = time.time()
195         try:
196             self.wait_element(element)
197             ActionChains(self.driver).double_click(self.find_element(element)).perform()
198             self.my_print(
199                 "{0} Double click element: <{1}>, Spend {2} seconds".format(success, element, time.time() - t1))
200         except Exception:
201             self.my_print(
202                 "{0} Unable to double click element: <{1}>, Spend {2} seconds".format(fail, element, time.time() - t1))
203         raise
204 
205     def drag_and_drop(self, source_element, target_element):
206 
207         t1 = time.time()
208         try:
209             self.wait_element(source_element)
210             self.wait_element(target_element)
211             ActionChains(self.driver).drag_and_drop(self.find_element(source_element),
212                                                     self.find_element(target_element)).perform()
213             self.my_print("{0} Drag and drop element: <{1}> to element: <{2}>, Spend {3} seconds".format(success,
214                                                                                                          source_element,
215                                                                                                          target_element,
216                                                                                                          time.time() - t1))
217         except Exception:
218             self.my_print("{0} Unable to drag and drop element: <{1}> to element: <{2}>, Spend {3} seconds".format(fail,
219                                                                                                                    source_element,
220                                                                                                                    target_element,
221                                                                                                                    time.time() - t1))
222         raise
223 
224     def back(self):
225 
226         t1 = time.time()
227         self.driver.back()
228         self.my_print("{0} Back to old window, Spend {1} seconds".format(success, time.time() - t1))
229 
230     def forward(self):
231 
232         t1 = time.time()
233         self.driver.forward()
234         self.my_print("{0} Forward to old window, Spend {1} seconds".format(success, time.time() - t1))
235 
236     def get_attribute_on(self, element, attribute):
237 
238         t1 = time.time()
239         try:
240             self.wait_element(element)
241             attr = self.find_element(element).get_attribute(attribute)
242             self.my_print("{0} Get attribute element: <{1}>,attribute: {2}, Spend {3} seconds".format(success,
243                                                                                                       element,
244                                                                                                       attribute,
245                                                                                                       time.time() - t1))
246             return attr
247         except Exception:
248             self.my_print("{0} Unable to get attribute element: <{1}>,attribute: {2}, Spend {3} seconds".format(fail,
249                                                                                                                 element,
250                                                                                                                 attribute,
251                                                                                                                 time.time() - t1))
252             raise
253 
254     def get_text(self, element):
255 
256         t1 = time.time()
257 
258         try:
259             self.wait_element(element)
260             text = self.find_element(element).text
261             self.my_print(
262                 "{0} Get element text element: <{1}>, Spend {2} seconds".format(success, element, time.time() - t1))
263             return text
264         except Exception:
265             self.my_print(
266                 "{0} Unable to get element text element: <{1}>, Spend {2} seconds".format(fail, element,
267                                                                                           time.time() - t1))
268             raise
269 
270     def get_display(self, element):
271 
272         t1 = time.time()
273         try:
274             self.wait_element(element)
275             self.find_element(element).is_displayed()
276             self.my_print("{0} the element is display, Spend {1} seconds".format(success, time.time() - t1))
277             return True
278         except Exception:
279             self.my_print("{0} the element is not display, Spend {1} seconds".format(fail, time.time() - t1))
280             return False
281 
282     def get_title(self):
283 
284         t1 = time.time()
285         title = self.driver.title
286         self.my_print("{0} Get current window title, Spend {1} seconds".format(success, time.time() - t1))
287         return title
288 
289     def get_url(self):
290 
291         t1 = time.time()
292         url = self.driver.current_url
293         self.my_print("{0} Get current window url, Spend {1} seconds".format(success, time.time() - t1))
294         return url
295 
296     def get_screenshot(self, file_name):
297 
298         t1 = time.time()
299         try:
300             file_path = img_path + file_name
301             self.driver.get_screenshot_as_file(file_path)
302             self.my_print("{0} Get the current window screenshot,path: {1}, Spend {2} seconds".format(success,
303                                                                                                       file_path,
304                                                                                                       time.time() - t1))
305         except Exception:
306             self.my_print("{0} Unable to get the current window screenshot,path: {1}, Spend {2} seconds".format(fail,
307                                                                                                                 file_path,
308                                                                                                                 time.time() - t1))
309             raise
310 
311     def submit(self, element):
312 
313         t1 = time.time()
314         try:
315             self.wait_element(element)
316             self.find_element(element).submit()
317             self.my_print(
318                 "{0} Submit form args element: <{1}>, Spend {2} seconds".format(success, element, time.time() - t1))
319         except Exception:
320             self.my_print(
321                 "{0} Unable to submit form args element: <{1}>, Spend {2} seconds".format(fail, element,
322                                                                                           time.time() - t1))
323         raise
324 
325     def switch_to_frame(self, element):
326 
327         t1 = time.time()
328         try:
329             self.wait_element(element)
330             self.driver.switch_to.frame(self.find_element(element))
331 
332             self.my_print(
333                 "{0} Switch to frame element: <{1}>, Spend {2} seconds".format(success, element, time.time() - t1))
334         except Exception:
335             self.my_print(
336                 "{0} Unable switch to frame element: <{1}>, Spend {2} seconds".format(fail, element, time.time() - t1))
337             raise
338 
339     def switch_to_frame_out(self):
340 
341         t1 = time.time()
342         self.driver.switch_to.default_content()
343         self.my_print("{0} Switch to frame out, Spend {1} seconds".format(success, time.time() - t1))
344 
345     def switch_new_window(self, element):
346 
347         t1 = time.time()
348         try:
349             current_windows = self.driver.current_window_handle
350             self.find_element(element).click()
351             all_handles = self.driver.window_handles
352             for handle in all_handles:
353                 if handle != current_windows:
354                     self.driver.switch_to.window(handle)
355             self.my_print("{0} Click element: <{1}> open a new window and swich into, Spend {2} seconds".format(success,
356                                                                                                                 element,
357                                                                                                                 time.time() - t1))
358         except Exception:
359             self.my_print("{0} Click element: <{1}> open a new window and swich into, Spend {2} seconds".format(fail,
360                                                                                                                 element,
361                                                                                                                 time.time() - t1))
362             raise
363 
364     def into_new_window(self):
365 
366         t1 = time.time()
367         try:
368             all_handle = self.driver.window_handles
369             flag = 0
370             while len(all_handle) < 2:
371                 time.sleep(1)
372                 all_handle = self.driver.window_handles
373                 flag += 1
374                 if flag == 5:
375                     break
376             self.driver.switch_to.window(all_handle[-1])
377             self.my_print("{0} Switch to the new window,new window's url: {1}, Spend {2} seconds".format(success,
378                                                                                                          self.driver.current_url,
379                                                                                                          time.time() - t1))
380         except Exception:
381             self.my_print("{0} Unable switch to the new window, Spend {1} seconds".format(fail, time.time() - t1))
382             raise
383 
384     def F5(self):
385 
386         t1 = time
387         self.driver.refresh()
388         self.my_print("{0} Refresh the current page, Spend {1} seconds".format(success, time.time() - t1))
389 
390     def js(self, script):
391 
392         t1 = time.time()
393 
394         try:
395             self.driver.execute_script(script)
396             self.my_print(
397                 "{0} Execute javascript scripts: {1}, Spend {2} seconds".format(success, script, time.time() - t1))
398         except Exception:
399             self.my_print("{0} Unable to execute javascript scripts: {1}, Spend {2} seconds".format(fail,
400                                                                                                     script,
401                                                                                                     time.time() - t1))
402             raise
403 
404     def accept_alert(self):
405 
406         t1 = time.time()
407 
408         self.driver.switch_to.alert.accept()
409         self.my_print("{0} Accept warning box, Spend {1} seconds".format(success, time.time() - t1))
410 
411     def dismiss_alert(self):
412 
413         t1 = time.time()
414         self.driver.switch_to.alert.dismiss()
415         self.my_print("{0} Dismisses the alert available, Spend {1} seconds".format(success, time.time() - t1))
416 
417     def close(self):
418 
419         t1 = time.time()
420         self.driver.close()
421         self.my_print("{0} Closed current window, Spend {1} seconds".format(success, time.time() - t1))
422 
423     def quit(self):
424 
425         t1 = time.time()
426         self.driver.quit()
427         self.my_print("{0} Closed all window and quit the driver, Spend {1} seconds".format(success, time.time() - t1))
428 
429     def element_exist(self, element):
430 
431         t1 = time.time()
432         try:
433             self.wait_element(element)
434             self.my_print("{0} Element: <{1}> is exist, Spend {2} seconds".format(success, element, time.time() - t1))
435             return True
436         except TimeoutException:
437             self.my_print("{0} Element: <{1}> is not exist, Spend {2} seconds".format(fail, element, time.time() - t1))
438             return False
439 
440     @property
441     def origin_driver(self):
442 
443         return self.driver
444 
445     def js_click(self, element):
446 
447         t1 = time.time()
448         js_str = "$('{0}').click()".format(element)
449         try:
450             self.driver.execute_script(js_str)
451             self.my_print(
452                 "{0} Use javascript click element: {1}, Spend {2} seconds".format(success, js_str, time.time() - t1))
453         except Exception:
454             self.my_print("{0} Unable to use javascript click element: {1}, Spend {2} seconds".format(fail,
455                                                                                                       js_str,
456                                                                                                       time.time() - t1))
457             raise
458 
459 
460 
461 
462 
463 
464 if __name__ == '__main__':
465     dr = base_frame()
466     dr.open('http://www.baidu.com')
467     dr.max_window()
468     dr.find_element('id=kw')
469     dr.get_screenshot('1.jpg')
470     dr.close()
View Code

 

 
get_config.py 获取配置文件
get_config.py
 
 1 import configparser
 2 import os
 3 import sys
 4 
 5 BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
 6 conf_dir = BASE_DIR + '/config/config.ini'
 7 conf_dir = conf_dir.replace('/', '\\')
 8 
 9 class Config(object):
10 
11     def __init__(self, path):
12         self.path = path
13         self.cf = configparser.ConfigParser()
14         self.cf.read(self.path, encoding='utf-8')
15 
16     def get(self, field, key):
17         result = ""
18         try:
19             result = self.cf.get(field, key)
20         except:
21             result = ""
22         return result
23 
24     def set(self, field, key, value):
25         try:
26             self.cf.set(field, key, value)
27             self.cf.write(open(self.path, 'w'))
28         except:
29             return False
30         return True
31 
32 
33 def r_config(config_file_path, field, key):
34     rf = configparser.ConfigParser()
35     try:
36         rf.read(config_file_path, encoding='utf-8')
37         result = rf.get(field, key)
38     except:
39         sys.exit(1)
40     return result
41 
42 
43 def w_config(config_file_path, field, key, value):
44     wf = configparser.ConfigParser()
45     try:
46         wf.read(config_file_path)
47         wf.set(field, key, value)
48         wf.write(open(config_file_path, 'w'))
49     except:
50         sys.exit(1)
51     return True
52 
53 
54 
55 
56 
57 if __name__ == '__main__':
58 
59 
60     b = r_config(conf_dir, 'image', 'img_path')
61     print(b)
View Code

 

get_db.py 连接数据库
get_db.py
1 import configparser
2 import os
3 import sys
4 
5 BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
6 conf_dir = BASE_DIR + '/config/config.ini'
7 conf_dir = conf_dir.replace('/', '\\')
View Code

 

 
get_excel.py 获取Excel
get_excel.py
1 import configparser
2 import os
3 import sys
4 
5 BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
6 conf_dir = BASE_DIR + '/config/config.ini'
7 conf_dir = conf_dir.replace('/', '\\')
View Code

 

 
get_files.py 获取测试报告
get_files.py
 1 import os, sys
 2 BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
 3 sys.path.append(BASE_DIR)
 4 
 5 
 6 # 查找最新生成的测试报告
 7 def get_new_file(files):
 8     lists = os.listdir(files)
 9     lists.sort(key=lambda fn: os.path.getmtime(files+fn))
10     file_ = os.path.join(files, lists[-1])
11     print(file_)
12     return file_
View Code

 

 
get_images.py 获取截图
get_images.py
 1 import os
 2 from public.common.get_config import r_config
 3 from selenium.webdriver import Remote
 4 from selenium import webdriver
 5 
 6 
 7 BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
 8 conf_path = BASE_DIR + '/config/config.ini'
 9 conf_path = conf_path.replace('/', '\\')
10 img_path = r_config(conf_path, "image", "img_path")
11 print(img_path)
12 
13 
14 
15 def insert_img(driver, file_name):
16     driver.get_screenshot_as_file(file_name)
17 
18 
19 
20 # 启动浏览器驱动
21 def browser():
22     driver = webdriver.Chrome()
23     '''
24     host = '127.0.0.1:4444' # 运行主机:端口号 (本机默认:127.0.0.1:4444)
25     dc = {'browserName': 'chrome'} # 指定浏览器('chrome','firefox',)
26     driver = Remote(command_executor='http://' + host + '/wd/hub',
27                     desired_capabilities=dc)
28     '''
29     return driver
30 
31 
32 
33 
34 
35 
36 if __name__ == '__main__':
37     driver = webdriver.Chrome()
38     driver.get("https://www.baidu.com")
39     insert_img('123')
40     driver.quit()
View Code

 

 
get_log.py 获取日志
get_log.py
 1 # coding=utf-8
 2 
 3 import os, sys, time, logging
 4 from public.common.get_config import r_config
 5 
 6 
 7 BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
 8 conf_path = BASE_DIR + '/config/config.ini'
 9 conf_path = conf_path.replace('/', '\\')
10 log_path = r_config(conf_path, "log", "log_path")
11 
12 
13 class Log():
14 
15     def __init__(self, conf_path):
16         self.logname = os.path.join(log_path, '{0}.log'.format(time.strftime('%Y-%m-%d')))
17 
18     def __printconsole(self, level, message):
19         # 创建一个logger
20         logger = logging.getLogger()
21         logger.setLevel(logging.DEBUG)
22         # 创建一个handler,用于写入日志文件
23         fh = logging.FileHandler(self.logname,'a',encoding='utf-8')
24         fh.setLevel(logging.DEBUG)
25         # 再创建一个handler,用于输出到控制台
26         ch = logging.StreamHandler()
27         ch.setLevel(logging.DEBUG)
28         # 定义handler的输出格式
29         formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
30         fh.setFormatter(formatter)
31         ch.setFormatter(formatter)
32         # 给logger添加handler
33         logger.addHandler(fh)
34         logger.addHandler(ch)
35         # 记录一条日志
36         if level == 'info':
37             logger.info(message)
38         elif level == 'debug':
39             logger.debug(message)
40         elif level == 'warning':
41             logger.warning(message)
42         elif level == 'error':
43             logger.error(message)
44         logger.removeHandler(ch)
45         logger.removeHandler(fh)
46         # 关闭打开的文件
47         fh.close()
48 
49     def debug(self, message):
50         self.__printconsole('debug', message)
51 
52     def info(self, message):
53         self.__printconsole('info', message)
54 
55     def warning(self, message):
56         self.__printconsole('warning', message)
57 
58     def error(self, message):
59         self.__printconsole('error', message)
60 
61 
62 if __name__ == '__main__':
63 
64     Log(conf_path)
View Code

 

 
my_unit.py unittest开始和结束,净化测试环境
my_unit.py
 1 import os
 2 import unittest
 3 BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
 4 conf_path = BASE_DIR + '/config/config.ini'
 5 conf_path = conf_path.replace('/', '\\')
 6 from public.common.get_config import r_config
 7 from public.common.get_log import Log
 8 from public.common.get_images import browser, insert_img
 9 
10 img_path = r_config(conf_path, 'image', 'img_path')
11 
12 class MyTest(unittest.TestCase):
13 
14     global case_count
15     case_count = 0
16 
17     global image_count
18     image_count = 0
19 
20     # 计算测试用例的个数,用于显示在测试报告中
21     def case_id(self):
22         global case_count
23         case_count += 1
24         if case_count <= 9:
25             count = "00" + str(case_count)
26         elif case_count <= 99:
27             count = "0" + str(case_count)
28         else:
29             count = str(case_count)
30         return count
31 
32     # 测试完成,生成截图文件的名称
33     def image_id(self):
34         global image_count
35         image_count += 1
36         if image_count <= 9:
37             count = "00" + str(image_count)
38         elif image_count <= 99:
39             count = "0" + str(image_count)
40         else:
41             count = str(image_count)
42         return count
43 
44     def setUp(self):
45         self.logger = Log(os.path.join(os.path.dirname(os.path.dirname(os.getcwd())), 'conf/conf.ini'))
46         self.logger.info('############################### START ###############################')
47         self.driver = browser()
48         self.driver.implicitly_wait(10)
49         self.driver.maximize_window()
50         print("case " + str(self.case_id()))
51 
52     def tearDown(self):
53         img_id = self.image_id()
54         file_name =img_path + img_id + ".jpg"
55         print(file_name)
56         insert_img(self.driver, file_name)
57         self.driver.quit()
58         self.logger.info('###############################  End  ###############################')
View Code

 

 
send_email.py 获取配置文件
send_email.py
 1 from email.mime.text import MIMEText
 2 from email.utils import formataddr
 3 import smtplib, os, sys
 4 BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
 5 sys.path.append(BASE_DIR)
 6 
 7 
 8 
 9 def send_mail(file_new):
10 
11     mail_from = 'XX@XX.com'
12     mail_to = 'XX@XX.com'
13     f = open(file_new, 'rb')
14     mail_body = f.read()
15     f.close()
16 
17     msg = MIMEText(mail_body, _subtype='html', _charset='utf-8')
18     msg['From'] = formataddr(["XX", mail_from])
19     msg['To'] = formataddr(["XX", mail_to])
20     msg['Subject'] = u"自动化测试报告"
21     smtp = smtplib.SMTP('smtp.exmail.qq.com', '25')
22     smtp.login('XX@XX.com', 'XX%')
23     smtp.sendmail(mail_from, mail_to, msg.as_string())
24     smtp.quit()
25     print('email has send out !')
View Code

 

pakeage:
存放第三方的包,浏览器的驱动等
HTMLTestRunner3.py
HTMLTestRunner3.py
 
 
2.3 测试报告以及日志
存放测试报告以及日志
image:存放测试截图
log:存放的日志文件
report: 存放测试报告
 
2.4 testcase
存放测试用例,测试用例需要以 test 开头
login_case.py
login_case.py
 
 1 from time import sleep
 2 import unittest, random, sys, os
 3 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 4 conf = BASE_DIR + '/config/config.ini'
 5 
 6 public = base = BASE_DIR + '/public'
 7 common = BASE_DIR + '/public/common'
 8 base = BASE_DIR + '/public/base'
 9 
10 conf_path = conf.replace('/', '\\')
11 public_path = public.replace('/', '\\')
12 common_path = common.replace('/', '\\')
13 base_path = base.replace('/', '\\')
14 
15 sys.path.append(conf_path)
16 sys.path.append(public_path)
17 sys.path.append(base_path)
18 sys.path.append(common_path)
19 
20 from public.common import my_unit
21 from public.base.login_page import LoginPage
22 
23 
24 
25 
26 class loginTest(my_unit.MyTest):
27     '''社区登录测试'''
28 
29     def test_login_user_pawd_null(self):
30         '''用户名、密码为空登录'''
31         po = LoginPage(self.driver)
32         po.open('http://192.168.20.12:8080/nisdn_platform/')
33         username = ""
34         passwd = ""
35         po.pro(username, passwd)
36         sleep(2)
37         self.assertEqual(po.error_text(), '用户名不能为空!')
38 
39     def test_login_pawd_null(self):
40         '''密码为空登录'''
41         po = LoginPage(self.driver)
42         po.open('http://192.168.20.12:8080/nisdn_platform/')
43         username = "admin"
44         passwd = ""
45         po.pro(username, passwd)
46         sleep(2)
47         self.assertEqual(po.error_text(), '密码不能为空!')
48 
49     def test_login_user_pawd_error(self):
50         '''用户名、密码为错误'''
51         po = LoginPage(self.driver)
52         po.open('http://192.168.20.12:8080/nisdn_platform/')
53         character = random.choice('zyxwvutsrqponmlkjihgfedcba')
54         username = "admin" + character
55         passwd = "admin"
56         po.pro(username, passwd)
57         sleep(2)
58         self.assertEqual(po.error_text(), '用户名只能输入字母或者数字!!')
59 
60     def test_login_success(self):
61         '''用户名、密码正确,登录成功'''
62         po = LoginPage(self.driver)
63         po.open('http://192.168.20.12:8080/nisdn_platform/')
64         user = "admin"
65         passwd = "admin"
66         po.pro(user, passwd)
67         sleep(2)
68 
69 
70 
71 if __name__ == '__main__':
72     #unittest.main()
73     suit = unittest.TestSuite()
74     suit.addTest(loginTest("test_login_success"))
75     runner = unittest.TextTestRunner()
76     runner.run(suit)
View Code

 

2.5 run_all.py
程序的入口
 
 1 import os, sys, time, unittest
 2 BASE_DIR = os.path.dirname(os.path.abspath(__file__))
 3 conf = BASE_DIR + '/config/config.ini'
 4 public = base = BASE_DIR + '/public'
 5 common = BASE_DIR + '/public/common'
 6 base = BASE_DIR + '/public/base'
 7 conf_path = conf.replace('/', '\\')
 8 public_path = public.replace('/', '\\')
 9 common_path = common.replace('/', '\\')
10 base_path = base.replace('/', '\\')
11 sys.path.append(conf_path)
12 sys.path.append(public_path)
13 sys.path.append(base_path)
14 sys.path.append(common_path)
15 from public.common.send_email import send_mail
16 from public.pakeage.HTMLTestRunner3 import HTMLTestRunner
17 from public.common.get_config import r_config
18 from public.common.get_files import get_new_file
19 
20 img_path = r_config(conf_path, 'image', 'img_path')
21 log_path = r_config(conf_path, 'log', 'log_path')
22 report_path = r_config(conf_path, 'report', 'report_path')
23 test_case_path = r_config(conf_path, 'test_case', 'test_case_path')
24 
25 
26 if __name__ == '__main__':
27     now_time = time.strftime("%Y-%m-%d-%H-%M-%S")
28     fp = open(report_path + now_time + "_result.html", 'wb')
29     runner = HTMLTestRunner(fp, title="网易邮箱测试报告", description="运行环境:macOS Sierra, chrome")
30     discover = unittest.defaultTestLoader.discover(test_case_path, pattern='login_*.py')
31     runner.run(discover)
32     fp.close()
33     file_path = get_new_file(report_path)
34     send_mail(file_path)
View Code

 

 
3、程序源码
posted @ 2017-09-22 11:32  luhongyuan  阅读(623)  评论(0)    收藏  举报