一个菜鸟测试工程师的简易自动化测试框架
上一篇 / 下一篇 2012-09-07 11:24:05 / 个人分类:自动化测试
~ ?z:tAa{-W8yI@0 引子
[Ke2G(]T*m051Testing软件测试网,ol*f9T&pQ1I$bz D7fd作为一个无 dev 经验的 tester 来说,目前遇到许多新的问题,关于 tester 以后的人员基本素质的构成,现在也有许多说法,在这里,不想过多的铺开讨论了。 作为一个 tester,本身当然必须对test这件事情感兴趣,才能把工作做好。 有的人天生喜欢找茬,喜欢提意见,在我看来,就是一个不错的 tester 的料。 当你天天对着同一个产品的不同版本不停的测试的时候,自然会产生一些怨言,由此产生懈怠。
%{ T[ uX+Z&`{D0'SH9F cW&Eve0 “某些功能点我都连着测试了 N 个版本了,肯定不会出错了” “这种基本功能点,怎么可能出错”这样的论调是很有可能产生的。于是,一个 tester 很有可能在某次 release 的过程中,经验主义的放过了某些功能点的测试。 几天后,一个用户反馈上来,那个功能点出了问题.........
Q-K(G0r_0nYZ(lb0 “偷懒”这个词语,在测试过程中,不应该算一个贬义词(当然了,故意漏过功能点不测试,不在此列)。因为“偷懒”催生新的技术,“偷懒”节省更多的时间。 我相信,自动化测试就是这样来的。
8h4g,h1t!kmxX,YAd;j051Testing软件测试网 Uk:_fA5_]1J正题
+I%H"]cUPTQ!Tt#W0;W+?:Qx|5J|3m0 任何事情都可以分解为很小的部分,让我们先分析一下,手工执行测试案例的一个过程:
/f|5i gP1S0r_h T0Lc2M)wm0 打开被测软件
#GW;OK#h9L'E2I0l8Ll"m\Z i0 执行测试案例
hV#a,Y-duz0'T ]n^:C8C0 给出测试结果
3CfnqY g2VJ1m051Testing软件测试网x^S6m"liRc({然后,我们不断重复这个过程。 最后给出测试报告。
-q#E!`8F"H}05x;~+jHU I2\#z1CG `0 显然,我们的自动化测试也要满足上面的这个过程中的所有要求。 既然是自动化,首先要求是所有的测试用例可以无人值守运行;其次,每个测试用例都由机器来模拟人对软件的操作;第三,某个测试用例失败不能影响其他测试用例的继续执行;第四,测试数据和测试用例最好分离开来;最后一点,测试结束之后,给个报告或者给个图告知测试结果。
3[6OE$vPmm0qv)q0BX+Y jn q0 根据上面的分析,我们逐个来一一解决,当然了,本篇都是很初级的解决方式,相信有许多大牛会有更好的方式来解决。
/A#Q)ks9x(]0yT+hdT!rIb0 无人值守运行,那么 python 的 unittest 的框架就能达到这个目的。51Testing软件测试网J:ks5|v6LrJ
9jw\2?]-EO"TO0y0 模拟人的操作, selenium 可以胜任。51Testing软件测试网a"J}T-u+b
51Testing软件测试网8pq^{5U ]1Ds测试用例间无影响, 同1
&{ h tY,q051Testing软件测试网f9Z B8G O#I数据分离, 那把测试数据都扔xml里。51Testing软件测试网 K:qE+gYW7@
0i:uq@*IAe0 待完善 (本例中 只是在部分方法中添加错误提示)51Testing软件测试网BF-j[9er7v:F
,N:B-B;N3y6oBw-n0 开始动手
cy t ]a)pS051Testing软件测试网&G(QsH vU对 python 的 unittest 进行一些小手术,当然了,如果只追求简单,直接用也行。51Testing软件测试网tS?Wx)Fa
def assertLogEqual(self, arg1, arg2):51Testing软件测试网ERw#_Y!Qprint "[assertLogEqual('"+arg1+"', '"+arg2+"')]: "51Testing软件测试网)xc.L:?"A$EZ;J [6D#D-B
if arg1 != arg2:
4Ir5L{*DZFO0self.anyfailure = True
-iVy2~h9S0print " -> Failed: not equal"
:A@ S6Hu0u2TV0l0self.result_note = " '%s' and 's%' is not equal\n "%(arg1,arg2)51Testing软件测试网I!s#TUl4f
else:51Testing软件测试网Z B?&H]z,CFY
print " ->OK"
nhM{%k0self.result_note = "%s OK\n" % self.result_note51Testing软件测试网lR v7Nt
self.assertEqual(arg1, arg2)51Testing软件测试网ETbT"LH!nJ0r
def assertLogTrue(self, arg1, note=""):
:pe ]{{;d0print "[assertLogTrue("+str(arg1)+")]: "+note51Testing软件测试网I2S(T7M Kr-J
if arg1 is False:51Testing软件测试网8bU]'Q"V'yy
self.anyfailure = True51Testing软件测试网tlR(hW{ Jj5r4m
print " -> Failed: Excepting True"
z&cly{*s0self.result_note = " %sError: %s\n " % (self.result_note, note)51Testing软件测试网"UK9o(?.Be$o^ C5C*E
else:51Testing软件测试网e4q4IZ'Y!dg0`
print " ->OK"51Testing软件测试网K|!~zphR,LO
self.resulte_note = "%s OK\n" % self.result_note
O_#_%M'^1E!a eQ:jb0self.assertTrue(arg1)
#uJ_q9eM ^)Q)U6T0def assertLogFalse(self, arg1, note=""):
^)W)Zi ]7xk)N/h0print "[assertLogFalse("+str(arg1)+")]: "+note51Testing软件测试网&w+}4?U^2x(Dj
if arg1 is True:
}cT k QjrL0print " ->FAILED: Expecting False."
yk.Cv l G9r`0self.anyfailure = True
|P!K9Qu;V\!EF L8z$Z0self.result_note = "%sError: %s\n" % (self.result_note, note)
/ex:g;P2W0else:
@a o r8[*LoG F,v0self.result_note = "%sOK\n" % self.result_note51Testing软件测试网X%? Bt+X&Zo
print " ->OK"
1J~_+?n)n@0self.assertFalse(arg1)
pA8Qr"Q/U0BY],v051Testing软件测试网M y L?;D'J
自己新建一个类,继承unittest,然后修改必要的一些方法,并添加部分方法,譬如设置testName啊,设置标记值来标记case知否执行结束啊。这些都是可以根据自己喜好来加入的方法。
3XMP,Q-NP,{,cO06S[J0Y?Z1R%S051Testing软件测试网c'J2a |9r
def setTestName(self, tname): #^f:h5fQe0self.testname = tname f&tm2K%CgW0def getTestName(self): *P*WQ*m7Q5m'Ip0return self.testname51Testing软件测试网4r"dP.hL kp def setCompleted(self): 9K b1u'b2E{ Z4v0self.completed = True51Testing软件测试网1~^H5@vN*A def isCompleted(self): q/tGQe X0return self.completed |
对于unittest框架的修改 就写这么多。
*| n)I7E"?@-f3sl#C0[8M5BD/y3P9lhc0 对selenium的基本方法做一些小改动,动机优化 unittest 框架一致,只是为了让你的用例跑起来的时候更加让人理解。我们相当于在 selenium 的基本方法外面又封装了一层。下面是部分方法示例:51Testing软件测试网s3[PcSz^0QN+@
51Testing软件测试网$\puNS`s!V1DK%D X]X,I0def open(self,url): `uX6Qv#B5e0self.sel.open(url)51Testing软件测试网+fk/Q k%P;a H&m:M def GetValue(self, element): "C_J$M@?q!K7B7V0value = self.sel.get_value(element) g O_+?6t$pq4@0self.assertLogTrue(True, "Value for element %s is %s" %(element, value)) Cgp.z"}9|/?7zS)H5w0return value "@.tm$h%G0def isTextPresent(self, text):51Testing软件测试网Qx8v$r&[&T'|se val = self.sel.is_text_present(text) M:~G!P,Q3uRD7s0if val is False:51Testing软件测试网^u4eb3v | self.assertLogTrue(val, note="error occured *************" + text +\ (uq0e^)d8p0" not found")51Testing软件测试网OH"rv4nj else: 1fW&QL` `0print 'present (%s,%s)' % (text,val)51Testing软件测试网/Epkc#@2q&H return val51Testing软件测试网.i{V b4ZGn? def Select(self, element, selection): e5C(N*FaG0if self.isElementPresent(element):51Testing软件测试网&RjI#`,NG f self.sel.select(element, selection)51Testing软件测试网6IIQ u@'tS o def Check(self, element): ^3},VQ.]h'f0if self.isElementPresent(element): q)@`C}]W0on0self.sel.check(element) b8aaz/rN1P"va0def Type(self, element, text):51Testing软件测试网 l$`&m |