哈哈,看了以下两个帖子,综合下捣鼓出了这个对比的功能
@ianxiaohanxu
http://testerhome.com/topics/1389
@monkey
http://testerhome.com/topics/202
其实在https://github.com/gb112211/Adb-For-Test 里面有一个截取element进行对比的方法,但是在使用appium时是无法使用的,因为其用到了uiautomator命令。。。
在appium中截取界面某个element,也就是截取屏幕的部分区域进行对比,在以图片对比结果作为判断依据的时候还是有用的,直接上代码:
extend.py
<span class="c">#!/usr/bin/env python</span>
<span class="c">#coding=utf-8</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">platform</span>
<span class="kn">import</span> <span class="nn">tempfile</span>
<span class="kn">import</span> <span class="nn">shutil</span>
<span class="kn">from</span> <span class="nn">PIL</span> <span class="kn">import</span> <span class="n">Image</span>
<span class="n">PATH</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">p</span><span class="p">:</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">abspath</span><span class="p">(</span><span class="n">p</span><span class="p">)</span>
<span class="n">TEMP_FILE</span> <span class="o">=</span> <span class="n">PATH</span><span class="p">(</span><span class="n">tempfile</span><span class="o">.</span><span class="n">gettempdir</span><span class="p">()</span> <span class="o">+</span> <span class="s">"/temp_screen.png"</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">Appium_Extend</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">driver</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">driver</span> <span class="o">=</span> <span class="n">driver</span>
<span class="k">def</span> <span class="nf">get_screenshot_by_element</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">element</span><span class="p">):</span>
<span class="c">#先截取整个屏幕,存储至系统临时目录下</span>
<span class="bp">self</span><span class="o">.</span><span class="n">driver</span><span class="o">.</span><span class="n">get_screenshot_as_file</span><span class="p">(</span><span class="n">TEMP_FILE</span><span class="p">)</span>
<span class="c">#获取元素bounds</span>
<span class="n">location</span> <span class="o">=</span> <span class="n">element</span><span class="o">.</span><span class="n">location</span>
<span class="n">size</span> <span class="o">=</span> <span class="n">element</span><span class="o">.</span><span class="n">size</span>
<span class="n">box</span> <span class="o">=</span> <span class="p">(</span><span class="n">location</span><span class="p">[</span><span class="s">"x"</span><span class="p">],</span> <span class="n">location</span><span class="p">[</span><span class="s">"y"</span><span class="p">],</span> <span class="n">location</span><span class="p">[</span><span class="s">"x"</span><span class="p">]</span> <span class="o">+</span> <span class="n">size</span><span class="p">[</span><span class="s">"width"</span><span class="p">],</span> <span class="n">location</span><span class="p">[</span><span class="s">"y"</span><span class="p">]</span> <span class="o">+</span> <span class="n">size</span><span class="p">[</span><span class="s">"height"</span><span class="p">])</span>
<span class="c">#截取图片</span>
<span class="n">image</span> <span class="o">=</span> <span class="n">Image</span><span class="o">.</span><span class="nb">open</span><span class="p">(</span><span class="n">TEMP_FILE</span><span class="p">)</span>
<span class="n">newImage</span> <span class="o">=</span> <span class="n">image</span><span class="o">.</span><span class="n">crop</span><span class="p">(</span><span class="n">box</span><span class="p">)</span>
<span class="n">newImage</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="n">TEMP_FILE</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span>
<span class="k">def</span> <span class="nf">get_screenshot_by_custom_size</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">start_x</span><span class="p">,</span> <span class="n">start_y</span><span class="p">,</span> <span class="n">end_x</span><span class="p">,</span> <span class="n">end_y</span><span class="p">):</span>
<span class="c">#自定义截取范围</span>
<span class="bp">self</span><span class="o">.</span><span class="n">driver</span><span class="o">.</span><span class="n">get_screenshot_as_file</span><span class="p">(</span><span class="n">TEMP_FILE</span><span class="p">)</span>
<span class="n">box</span> <span class="o">=</span> <span class="p">(</span><span class="n">start_x</span><span class="p">,</span> <span class="n">start_y</span><span class="p">,</span> <span class="n">end_x</span><span class="p">,</span> <span class="n">end_y</span><span class="p">)</span>
<span class="n">image</span> <span class="o">=</span> <span class="n">Image</span><span class="o">.</span><span class="nb">open</span><span class="p">(</span><span class="n">TEMP_FILE</span><span class="p">)</span>
<span class="n">newImage</span> <span class="o">=</span> <span class="n">image</span><span class="o">.</span><span class="n">crop</span><span class="p">(</span><span class="n">box</span><span class="p">)</span>
<span class="n">newImage</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="n">TEMP_FILE</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span>
<span class="k">def</span> <span class="nf">write_to_file</span><span class="p">(</span> <span class="bp">self</span><span class="p">,</span> <span class="n">dirPath</span><span class="p">,</span> <span class="n">imageName</span><span class="p">,</span> <span class="n">form</span> <span class="o">=</span> <span class="s">"png"</span><span class="p">):</span>
<span class="c">#将截屏文件复制到指定目录下</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isdir</span><span class="p">(</span><span class="n">dirPath</span><span class="p">):</span>
<span class="n">os</span><span class="o">.</span><span class="n">makedirs</span><span class="p">(</span><span class="n">dirPath</span><span class="p">)</span>
<span class="n">shutil</span><span class="o">.</span><span class="n">copyfile</span><span class="p">(</span><span class="n">TEMP_FILE</span><span class="p">,</span> <span class="n">PATH</span><span class="p">(</span><span class="n">dirPath</span> <span class="o">+</span> <span class="s">"/"</span> <span class="o">+</span> <span class="n">imageName</span> <span class="o">+</span> <span class="s">"."</span> <span class="o">+</span> <span class="n">form</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">load_image</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">image_path</span><span class="p">):</span>
<span class="c">#加载目标图片供对比用</span>
<span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isfile</span><span class="p">(</span><span class="n">image_path</span><span class="p">):</span>
<span class="n">load</span> <span class="o">=</span> <span class="n">Image</span><span class="o">.</span><span class="nb">open</span><span class="p">(</span><span class="n">image_path</span><span class="p">)</span>
<span class="k">return</span> <span class="n">load</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">raise</span> <span class="nb">Exception</span><span class="p">(</span><span class="s">"</span><span class="si">%</span><span class="s">s is not exist"</span> <span class="o">%</span><span class="n">image_path</span><span class="p">)</span>
<span class="c">#http://testerhome.com/topics/202</span>
<span class="k">def</span> <span class="nf">same_as</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">load_image</span><span class="p">,</span> <span class="n">percent</span><span class="p">):</span>
<span class="c">#对比图片,percent值设为0,则100%相似时返回True,设置的值越大,相差越大</span>
<span class="kn">import</span> <span class="nn">math</span>
<span class="kn">import</span> <span class="nn">operator</span>
<span class="n">image1</span> <span class="o">=</span> <span class="n">Image</span><span class="o">.</span><span class="nb">open</span><span class="p">(</span><span class="n">TEMP_FILE</span><span class="p">)</span>
<span class="n">image2</span> <span class="o">=</span> <span class="n">load_image</span>
<span class="n">histogram1</span> <span class="o">=</span> <span class="n">image1</span><span class="o">.</span><span class="n">histogram</span><span class="p">()</span>
<span class="n">histogram2</span> <span class="o">=</span> <span class="n">image2</span><span class="o">.</span><span class="n">histogram</span><span class="p">()</span>
<span class="n">differ</span> <span class="o">=</span> <span class="n">math</span><span class="o">.</span><span class="n">sqrt</span><span class="p">(</span><span class="nb">reduce</span><span class="p">(</span><span class="n">operator</span><span class="o">.</span><span class="n">add</span><span class="p">,</span> <span class="nb">list</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="k">lambda</span> <span class="n">a</span><span class="p">,</span><span class="n">b</span><span class="p">:</span> <span class="p">(</span><span class="n">a</span><span class="o">-</span><span class="n">b</span><span class="p">)</span><span class="o">**</span><span class="mi">2</span><span class="p">,</span> \
<span class="n">histogram1</span><span class="p">,</span> <span class="n">histogram2</span><span class="p">)))</span><span class="o">/</span><span class="nb">len</span><span class="p">(</span><span class="n">histogram1</span><span class="p">))</span>
<span class="k">if</span> <span class="n">differ</span> <span class="o"><=</span> <span class="n">percent</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">True</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">False</span>
接着跑了个appium脚本简单测试了下:
extend_test.py
<span class="c">#coding=utf-8</span>
<span class="kn">import</span> <span class="nn">unittest</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">from</span> <span class="nn">extend</span> <span class="kn">import</span> <span class="n">Appium_Extend</span>
<span class="kn">from</span> <span class="nn">appium</span> <span class="kn">import</span> <span class="n">webdriver</span>
<span class="k">class</span> <span class="nc">Test</span><span class="p">(</span><span class="n">unittest</span><span class="o">.</span><span class="n">TestCase</span><span class="p">):</span>
<span class="c">#初始化环境</span>
<span class="k">def</span> <span class="nf">setUp</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">desired_caps</span> <span class="o">=</span> <span class="p">{}</span>
<span class="n">desired_caps</span><span class="p">[</span><span class="s">"platformName"</span><span class="p">]</span> <span class="o">=</span> <span class="s">"Android"</span>
<span class="n">desired_caps</span><span class="p">[</span><span class="s">"platformVersion"</span><span class="p">]</span> <span class="o">=</span> <span class="s">"4.3"</span>
<span class="n">desired_caps</span><span class="p">[</span><span class="s">"deviceName"</span><span class="p">]</span> <span class="o">=</span> <span class="s">"788a6ab5"</span>
<span class="n">desired_caps</span><span class="p">[</span><span class="s">"appPackage"</span><span class="p">]</span> <span class="o">=</span> <span class="s">"com.android.settings"</span>
<span class="n">desired_caps</span><span class="p">[</span><span class="s">"appActivity"</span><span class="p">]</span> <span class="o">=</span> <span class="s">".Settings"</span>
<span class="bp">self</span><span class="o">.</span><span class="n">driver</span> <span class="o">=</span> <span class="n">webdriver</span><span class="o">.</span><span class="n">Remote</span><span class="p">(</span><span class="s">"http://127.0.0.1:4723/wd/hub"</span><span class="p">,</span> <span class="n">desired_caps</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">extend</span> <span class="o">=</span> <span class="n">Appium_Extend</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">driver</span><span class="p">)</span>
<span class="c">#回到主屏幕</span>
<span class="bp">self</span><span class="o">.</span><span class="n">driver</span><span class="o">.</span><span class="n">press_keycode</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="c">#退出测试</span>
<span class="k">def</span> <span class="nf">tearDown</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">driver</span><span class="o">.</span><span class="n">quit</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">test_get_screen_by_element</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">element</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">driver</span><span class="o">.</span><span class="n">find_element_by_id</span><span class="p">(</span><span class="s">"com.android.deskclock:id/imageview"</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">extend</span><span class="o">.</span><span class="n">get_screenshot_by_element</span><span class="p">(</span><span class="n">element</span><span class="p">)</span><span class="o">.</span><span class="n">write_to_file</span><span class="p">(</span><span class="s">"f:</span><span class="se">\\</span><span class="s">screen"</span><span class="p">,</span> <span class="s">"image"</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isfile</span><span class="p">(</span><span class="s">"f:</span><span class="se">\\</span><span class="s">screen</span><span class="se">\\</span><span class="s">image.png"</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">test_same_as</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">element</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">driver</span><span class="o">.</span><span class="n">find_element_by_id</span><span class="p">(</span><span class="s">"com.android.deskclock:id/imageview"</span><span class="p">)</span>
<span class="n">load</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">extend</span><span class="o">.</span><span class="n">load_image</span><span class="p">(</span><span class="s">"f:</span><span class="se">\\</span><span class="s">screen</span><span class="se">\\</span><span class="s">image.png"</span><span class="p">)</span>
<span class="c">#要求百分百相似</span>
<span class="n">result</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">extend</span><span class="o">.</span><span class="n">get_screenshot_by_element</span><span class="p">(</span><span class="n">element</span><span class="p">)</span><span class="o">.</span><span class="n">same_as</span><span class="p">(</span><span class="n">load</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertTrue</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">"__main__"</span><span class="p">:</span>
<span class="n">suite</span> <span class="o">=</span> <span class="n">unittest</span><span class="o">.</span><span class="n">TestSuite</span><span class="p">()</span>
<span class="n">suite</span><span class="o">.</span><span class="n">addTest</span><span class="p">(</span><span class="n">Test</span><span class="p">(</span><span class="s">"test_get_screen_by_element"</span><span class="p">))</span>
<span class="n">suite</span><span class="o">.</span><span class="n">addTest</span><span class="p">(</span><span class="n">Test</span><span class="p">(</span><span class="s">"test_same_as"</span><span class="p">))</span>
<span class="c">#执行测试</span>
<span class="n">unittest</span><span class="o">.</span><span class="n">TextTestRunner</span><span class="p">()</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">suite</span><span class="p">)</span>
这里截取的图片是下面这张图中的时间插件:
截取后的图片:
![](https://i-blog.csdnimg.cn/blog_migrate/00147f9666198dd0fc500208f0c8a2ee.png)
另外批量截图、批量对比就针对需求再做扩展了!