在 Mac 上執行自動化測試遇到錯誤時,透過 Python 截圖

在 Mac OS 上執行自動化測試程式,如果有遇到問題,該如何保持案發現場?其中一步就是將螢幕截圖!
可使用 Python 的 “subprocess” 模組內的 “call” function,帶入截圖的 shell script 來達成目的。如以下所示:

from subprocess import call
call(["screencapture", "screenshots.jpg"])

這樣的執行方式等同於在 terminal 直接執行 screencapture 的 shell script:

$ screencapture screenshots.jpg

套用我們在 Mac 上的 ATOMAC 自動化測試,就可以在出現不預期的情況下,做螢幕截圖:
(以下例子是給予預期值 ‘3’,但實際 App 測試的結果是 ‘2’,兩相不符合而 throw exception,進入截圖程序)

# -*- coding: utf-8 -*-

import time
import datetime
import unittest
import atomac
import sys
from subprocess import call

class AlmightyCalculatorTestCase(unittest.TestCase):

    atomac.launchAppByBundleId('com.ktpd.Calculator') # Open Calculator via BundleId of this app
    calculator = atomac.getAppRefByLocalizedName('Almighty Calculator') # Get the ref. of the app

    def setUp(self):
        print ('\'\n---- (%s) %s ----\n' %(time.strftime("%Y/%m/%d %H:%M:%S"), self.id()))
        self.calculator.findFirstR(AXRole='AXButton', AXTitle='C').Press()
        time.sleep(1)

    def tearDown(self):
        pass

    def press_equals_button(self):
        equal_button = self.calculator.findFirstR(AXRole='AXButton', AXTitle='=')
        equal_button.Press()

    def screencapture(self):
        t = time.time()
        screencapture_file =  datetime.datetime.fromtimestamp(t).strftime('%Y-%m-%d_%H-%M-%S')
        call(["screencapture", "./test_screenshots/%s.jpg" %(screencapture_file)])

    def test_1_one_plus_one(self):
        try:
            self.calculator.findFirstR(AXRole='AXButton', AXTitle='1').Press()
            self.calculator.findFirstR(AXRole='AXButton', AXTitle='+').Press()
            self.calculator.findFirstR(AXRole='AXButton', AXTitle='1').Press()
            self.calculator.findFirstR(AXRole='AXButton', AXTitle='=').Press()

            value = self.calculator.findFirstR(AXRole='AXStaticText', AXRoleDescription='text').AXValue
            # Let the result not equal to the expected, then throw exception.
            expected_value = 3
            self.assertEqual(str(expected_value), value)

        except:
            print 'Unexpected error:', sys.exc_info()[0]
            self.screencapture()
            raise

if __name__ == '__main__':
unittest.main()

當測試遇到不符合預期時就會幫我們截圖,如此我們就可以得到問題當下的情況。
python screencapture

再比對 Console Output Log 可以發現,原來預期的值是 ‘3’,但實際 App 測試的結果是 ‘2’,兩者並不相符合,與我們的截圖一致。

[Console Output]
ChloetekiMacBook-Air@ChloeChen:~/Desktop/DemoSnapshot$ python demo_calculator.py
'
---- (2014/05/28 22:43:23) __main__.AlmightyCalculatorTestCase.test_1_one_plus_one ----

Unexpected error: <type 'exceptions.AssertionError'>
libpng warning: zero length keyword
libpng warning: Empty language field in iTXt chunk
F
======================================================================
FAIL: test_1_one_plus_one (__main__.AlmightyCalculatorTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "demo_calculator.py", line 42, in test_1_one_plus_one
self.assertEqual(str(expected_value), value)
AssertionError: '3' != u'2'

----------------------------------------------------------------------
Ran 1 test in 1.789s

FAILED (failures=1)

 

對了,你可能會發現畫面輸出中有兩行 warning,這兩行 warining 其實沒有什麼影響,可以忽視他們沒關係。(參此討論 – screencapture from Terminal

libpng warning: zero length keyword
libpng warning: Empty language field in iTXt chunk

參考資料
1. Python Doc – 17.1.1. Using the subprocess Module
2. Python Doc – 8. Errors and Exceptions
3. Shell Scripting in Python (in 在電梯裡遇見雙胞胎)
4. Discussion of screencapture from Terminal(in Apple Support Communities)

廣告

發表迴響

Please log in using one of these methods to post your comment:

WordPress.com Logo

您的留言將使用 WordPress.com 帳號。 登出 / 變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 / 變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 / 變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 / 變更 )

連結到 %s