UI自动化,换种思路,把执行步骤换成动图gif
看了很多UI自动化框架,无论是开源的还是自己造轮子的,都是失败后截最后一张图或几张图。随然没有问题。但我们能不能换种思想。我们能不能把截图全转成gif动图,这样定位问题更直观呢。
来吧。看看怎么实现吧。
先看看楼主的思路吧,如下:
每一个用例中的步骤我们都截图,然后再保存至对应用例的文件夹中,在跑完用例后,将文件夹中的图片转成gif文件,再删除其它静态图片。
思路有了,再看看怎么实现吧。背景是我们用的pytest框架,基于unitest Fixture
一、解析用例名
这步主要是用于获取用例名,用于后面新建对应的用例名文件夹
def get_testname(self): full_stack = inspect.stack() index = -1 for stack_frame in full_stack: print(stack_frame[1],stack_frame[3]) if 'test_' in stack_frame[3]: index = full_stack.index(stack_frame) break testname = full_stack[index][3] return testname
其中,这里筛选出来的是以含有test_的用例。可根据需要自己修改。
二、截图的保存
这里的思路就是每一个用例根据用例名创建文件夹,然后再将截图存入
def save_screenshot(self,screenshot_name): "Take a screenshot" self.screenshots_parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'screenshots')) if not os.path.exists(self.screenshots_parent_dir): os.makedirs(self.screenshots_parent_dir) self.logs_parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'log')) if not os.path.exists(self.logs_parent_dir): os.makedirs(self.logs_parent_dir) self.screenshot_dir = self.screenshots_parent_dir + os.sep + self.gettestname() if not os.path.exists(self.screenshot_dir): os.makedirs(self.screenshot_dir) if os.path.exists(self.screenshot_dir + os.sep + screenshot_name+'.png'): for i in range(1,100): if os.path.exists(self.screenshot_dir + os.sep +screenshot_name+'_'+str(i)+'.png'): continue else: os.rename(self.screenshot_dir + os.sep +screenshot_name+'.png',self.screenshot_dir + os.sep +screenshot_name+'_'+str(i)+'.png') break screenshot_name = self.screenshot_dir + os.sep + screenshot_name+'.png' self.driver.get_screenshot_as_file(screenshot_name)
三、写装饰器用于步骤的截图
class Wrapit(): def _screenshot(func): def wrapper(self, *args, **kwargs): result = func(self, *args, **kwargs) screenshot_name = '%003d' % self.screenshot_counter + '_' + func.__name__ self.screenshot_counter += 1 self.save_screenshot(screenshot_name) return result return wrapper
为了防止步骤一样,导致文件名重叠,所以加了一个计数器
四、将装饰器用于动作的封装中
@Wrapit._screenshot def input_name(self, text): self.driver.find_element_by_id('kw').send_keys(text)
五、生成gif
这步需要用于Pillow库
def make_gif(self, screenshot_dir_path, name = "test_png",suffix=".gif",duration=500): images = [] from PIL import Image filenames = os.listdir(screenshot_dir_path) gif_name = os.path.join(screenshot_dir_path, name + suffix) for files in sorted(filenames): im = Image.open(os.path.join(screenshot_dir_path, files)) images.append(im) images[0].save(gif_name, save_all=True, loop=True, append_images=images[1:], duration=duration)
六、删除其它png文件
def clean_png(self, screenshot_dir_path): filenames = os.listdir(screenshot_dir_path) fileanames = [name for name in filenames if name.endswith('.png')] for files in sorted(fileanames): print('remove file %s' % files) os.remove(os.path.join(screenshot_dir_path, files))
7、将生成gif和删除png动作放在teardown中
def tearDown(self) -> None: self.page.make_gif(self.page.screenshot_dir) self.clean_png(self.page.screenshot_dir)
完成后,会生成如果这样的gif
我的用例步骤是:
1.打开百度
2.输入xxxx
3.点击百度一下
4.再点击百度首页
------可能问题-----
你可能会问到。如果使用的是类继承,导致用例名是一样的,怎么处理?只需要修改获取用例名的函数的方法
未放完整的代码上去。如果有需要的朋友可以直接联系,一起探讨。
还需要优化的地方:
点击某个地方或者找某个元素,需要高亮一下。这样让定位更清晰
Email:362299908@qq.com