1 自动化测试框架
1.1 测试流程
1.1.1 测试流程图
自动化测试包括系统的安装和配置、模拟器的安装和配置、公用测试数据的准备、测试数据和配置的更新以及自动化测试脚本。如下图:
1.1.2 测试流程说明
系统测试准备:系统的安装和配置、模拟器的安装和配置、公用测试数据的准备这些动作,是自动化测试开始的前提,在自动化测试过程中的一次性行为。在系统测试中,公共的测试数据可以供整个系统使用,这些数据在系统安装配置完成后使用自动化测试脚本创建,创建好后存放在 XML 文件中。使用 XML 存放的好处是数据的复用。
功能测试类:同属某功能的测试用例放在同一个 JAVA 测试类中,该测试类从 XML 文件中读取公共测试数据并验证测试数据的合法性,如果测试数据合法则使用这些测试数据,否则创建一套新的公用测试数据并将这套公共测试数据存放到 XML 文件中供其它测试类使用。同时,创建适合这个功能测试类使用的测试数据,并配置适合该功能测试类的配置参数。
测试用例:如果某个测试用例需要某些特殊的测试配置和数据,在具体的某个测试用例开始的时候进行,在准备好数据后,获取当前测试数据的状态和设置预期结果,然后执行测试步骤,当所有的测试步骤都测试完成后检查测试结果。最后,一定要恢复测试环境,如果公共测试数据或配置被修改,一定要在测试用例结束的时候恢复。
1.2 测试结构
自动化测试框架由 Data, Action, Verification, Cases 和 Util 组成。如下图:
1.2.1 Data
主要用于存放公共测试数据的定义,比如要创建的公用测试数据的定义,创建测试数据的 Action 在创建数据的时候从 Data 定义文件中读取输入,然后创建符合测试要求的测试数据。
也用于存放数据结构的定义,比如,短消息的结构体定义或某测试对象的属性定义。
Data 中还会有常量定义,常量在整个系统中全局使用。
1.2.2 Action
在测试过程中需要进行的任何操作,比如:配置、创建数据、测试步骤等。
1.2.3 Verification
在测试完成后,对测试结果进行验证的类和方法。比如:检查接收到的广告内容是否正确。
1.2.4 Cases
测试用例存放目录,相关功能的测试用例放在同一测试子目录中,同一功能的测试用例放在同一个测试类中。
1.2.5 Util
主要是用于存放工具类。
1.3 命名规则
1.3.1 包( Package )
· All other letters are lowercase
· E.g. pushcampaign
1.3.2 类( Class )
· The first letter of every word is capital, all other letters lowercase
· The class including test cases should end with XXXTest.java, or else should be XXX.java
· For example: PushCampaignTest.java
1.3.3 变量( Variable )
· The first letter of the first word is lowercase.
· The first letter of the every word except the first word is capital.
· All other letters are lowercase.
· For example: dailyBudget.
1.3.4 常量( Constant )
· All letters are capital
· The name should be meaningful
· The name of different words should be joined by “_”
· The name should start with “DEFAULT”
· For example: DEFAULT_COUNTRY
1.4 基本原则
自动化测试的基本原则:
· Reliable
· Readable
· Extensible
· Maintainable
· Practicable
· Repeatable
2 Data
2.1 测试数据
测试数据可分为三种:公用测试数据、功能类测试数据和用例测试数据三种。
2.1.1 公用测试数据 (Common Test Data)
公用测试数据是测试系统中所有测试用例都能使用的数据,在自动化测试用例开始运行前首先创建一套供所有测试用例使用的公用测试数据,这些数据可以包括:
· Service Provider
· Publisher
· Publisher Pricing Agreement
· Site
· Inventories (One inventory for one channel)
· Ad Sales
· Ad Sales Pricing Agreement
· Media Agency
· Media Agency Pricing Agreement
· Campaign (One campaign for one campaign type)
· Consumer
公用数据应存放在 XML 文件中供所有测试类使用,测试类在测试开始前先从 XML 文件中读取测试数据,并验证测试数据的合法性,如果测试数据非法则需要重新创建并保存到 XML 文件中。
公用测试数据的创建流程:
· 根据数据定义文件创建公用测试数据 (createCommonTestData)
· 保存公用数据到 XML 文件中 (storeCommonTestDataToFile)
在测试类中使用公用数据的流程:
· 从 XML 文件中读取公用测试数据 (readCommonTestDataFromFile)
· 校验公用测试数据的合法性:存在于系统并且状态正常 (verifyCommonTestData) ,如果数据非法则重新创建。
使用公用数据的好处是避免重复创建测试数据,节省自动化测试的时间。而存放测试数据到 XML 的好处是一方面可以重复使用这些测试,另一方面是遇到问题的时候可以方便地使用保存在 XML 的测试数据进行问题跟踪。
公用测试数据不建议修改,如果非要修改,一定要记得恢复。
2.1.2 功能类测试数据 (Functionality Test Data)
同一功能的测试用例放在同一测试类中,当公用测试数据满足不了这个测试类并且某些测试数据又可以供这个测试类的大部分测试用例使用时,在测试用例开始运行前创建功能类测试数据。
2.1.3 用例测试数据 (Case Test Data)
某些测试用例需要特殊的测试数据,而且这些测试数据只适合于某个测试用例,则在这个测试用例测试前准备该测试用例的测试数据。
每个与广告投递相关的测试用例,都创建一个唯一的用户,这样做的好处是方便计费日志的检查,并且,当用例运行失败的时候,唯一的用户 ID 也方便定位出错的原因。
2.2 测试数据常量化
公用测试数据应该用常量定义,这些常量在创建数据、使用数据、校验测试结果的时候可以使用。这样可以避免测试数据写死在测试用例中,当某个值被改变或参数被删除的时候,所带来的维护工作量。
比如,每个广告投递一次需要 1 元,定义常量 CAMPAIGN_DELIVERY_COST=1 ,那么在数据创建的时候可以使用 CAMPAIGN_DELIVERY_COST 这个常量,并且在检查这个广告投递成功后是否扣除 1 元也可以使用这个常量。
2.3 测试数据结构体
测试数据或测试对象定义测试结构体,供 Action/Verification/Cases 使用,比如: Publisher 或 Campaign 这些测试数据根据它们的属性构成测试数据结构体;又如:短信广告内容这些被测试检查对象也根据他们的属性组成测试对象数据结构体。
3 Action
Action ,顾名思义,就是在测试的过程中所作的任何操作。 Action 在自动化测试中可分为所有或某些测试类都可以使用的公用 Action 和某类或某个测试用例使用功能类 Action 两种,而这两种 Action 又可以分为原子 Action 和组合 Action 。
Primitive Action 就是一个不可被分割的简单操作,而 Composite action 则是由若干个 Primitive Action 组成的操作,如果某几个 Primitive Action 会被两个以上的地方使用,那么这几个动作应该封装成一个 Composite Action 。
3.1 公用测试操作 (Common Action)
以下这些测试动作是全局使用的:
· getCampaignBudgetImpressionClicks
· getInventory
· getChannel
· optinConsumersByWebservice
以下这些测试动作,适合于所有 PUSH 广告相关的测试,包括 push campaign, survey campaign, incentive reward campaign 和 direct market campaign 等与 PUSH 相关的测试场景:
· configurePushEnvironment
· receiveSmsAd / receiveMmsAd
· returnSmsAdResponse / returnMmsAdResponse
· sendSmsAdDeliveryReport / sendMmsAdDeliveryReport
· receiveSmsAdDeliveryReportResponse / receiveMmsAdDeliveryReportResponse
· sendSmsMo / sendMmsMo
· receiveSmsMoResponse / receiveMmsMoResponse
这些 Action 都是一些原子操作,这些原子操作将会被每类广告的 Action 根据每类广告的业务逻辑调用组成复合操作。
3.2 功能类测试操作 (Functionality Action)
每类广告的测试场景所使用到的测试动作将放到对应的目录下。
3.2.1 Pull Campaign
Pull Campaign 的广告测试场景中,将会有这些 Primitive Action :
· fetchPullAd
· fetchPullAdContent
· clickPullAd
· sendPullAdDeliveryReport
· sendActionReport
· fetchRingBackAd
· sendRingBackAdDeliveryReport
Pull Campaign 的广告测试场景中,将会有这些由 Primitive Action 组合成的 Composite Action :
· fetchPullAdAndCheckReponse
· clickPullAdAndCheckResponse
· sendPullAdDeliveryReportAndCheckResponse
· sendActionReportAndCheckResponse
· fetchRingBackAdAndCheckResponse
· sendRingBackAdDeliveryReportAndCheckResponse
3.2.2 Push Campaign
在 PUSH CAMPAIGN 广告测试场景中,将会调用公用的 Primitive Action 组合成这些被测试用例调用的 Composite Action :
· receivePushAdAndCheckMessage
· clickPushAdAndCheckResponse
· receivePushAdButReturnFailResponse
· receivePushAdButNotReturnResponse
· receivePushAdButReturnFailDeliveryReport
· receivePushAdButNotReturnDeliveryReport
· receiveMultiplePushAdAndCheckMessage
3.2.3 Survey Campaign
在 Survey Campaign 广告测试场景中,将会调用公用的 Primitive Action 组合成这些被测试用例调用的 Composite Action :
· receiveSurveyAndReplyThenCheckMessage
· receiveSurveyButReplyInvalidFirstAnswer
· receiveSurveyButReturnFailedResponseForFirstQuestion
· receiveSurveyAndReplyButNotReturnResponseForLastQuestion
· receiveSurveyAndReplyButReturnFailedDeliveryReportForLastQuestion
· receiveSurveyButNotReplyAnyAnswer
4 Verification
Verification 就是对测试结果的校验。 Verification 在自动化测试中可分为所有或某些测试类都可以使用的公用 Verification 和某类或某个测试用例使用功能类 Verification 两种,而这两种 Verification 又可以分为 Primitive Verification 和 Composite Verification 。
Primitive Verification 就是一个不可被分割的简单操作,而 Composite Verification 则是由若干个 Primitive Verification 组成的操作,如果某几个 Primitive Verification 会被两个以上的地方使用,那么这几个动作应该封装成一个 Composite Verification 。
4.1 公用测试校验 (Common Verification)
在测试完成后,不管是哪类型的广告,都需要校验广告一次花费的钱、交易日志等:
· checkCampaignBudgetImpressionClicks
· checkTransactionLog
· checkImpressionLog
· checkClickLog
· checkReportingData
对于 PUSH 相关的广告,还需要校验递送历史、检查短信或彩信内容:
· checkDeliveryHistory
· checkSmsMessage
· checkMmsMessage
4.2 功能类测试校验 (Functionality Verification)
根据每类广告的测试场景的不同,相应的也会有不同的校验动作。
4.2.1 Pull Campaign
Pull Campaign 的广告测试场景中,会使用到这些 Primitive Verification :
· checkFetchPullAdResponse
· checkClickPullAdResponse
· checkSendPullAdDeliveryReportResponse
· checkSendActionReportResponse
· checkFetchRingBackAdResponse
· checkSendRingBackAdDeliveryReportResponse
Pull Campaign 的广告测试场景中,将会有这些 Primitive Action & Primitive Verification 组合成的 Composite Verification :
· fetchPullAdAndCheckReponse
· clickPullAdAndCheckResponse
· sendPullAdDeliveryReportAndCheckResponse
· sendActionReportAndCheckResponse
· fetchRingBackAdAndCheckResponse
· sendRingBackAdDeliveryReportAndCheckResponse
事实上,这是由 Primitive Action & Primitive Verification 组合的操作,原则上,动作应该和检验是分开的,但考虑到这个动作和校验之间的关系非常密切,并且每个原子动作的后面都跟一个原子校验的话,测试用例就会显得非常臃肿。
为了统一,所有由 Primitive Action & Primitive Verification 的组合都归类到 Action 中。
4.2.2 Push Campaign
在 PUSH CAMPAIGN 广告测试场景中,将会调用公用的 Primitive Verification :
· checkSmsMessage
- check msisdn and AD content
· checkMmsMessage
- check msisdn and AD content
· checkSmsAdDeliveryReportResponse / checkMmsAdDeliveryReportResponse
· checkSmsMoResponse / checkMmsMoResponse
和 Pull Campaign 的广告测试场景一样,在 Push Campaign 的测试场景中,也会有这些 Primitive Action & Primitive Verification 组合成的 Composite Verification :
· receivePushAdAndCheckMessage
· clickPushAdAndCheckResponse
· receivePushAdButReturnFailResponse
· receivePushAdButNotReturnResponse
· receivePushAdButReturnFailDeliveryReport
· receivePushAdButNotReturnDeliveryReport
· receiveMultiplePushAdAndCheckMessage
同样地,在 PUSH CAMPAIGN 测试中,所有由 Primitive Action & Primitive Verification 的组合都归类到 Action 中。
4.2.3 Survey Campaign
在 Survey Campaign 广告测试场景中,将会调用公用的 Primitive Verification 组合成这些被测试用例调用的 Composite Verification :
· checkSurveyTransactionLog
和 Pull Campaign 的广告测试场景一样,在 Push Campaign 的测试场景中,也会有这些 Primitive Action & Primitive Verification 组合成的 Composite Verification :
· receiveSurveyAndReplyThenCheckMessage
· receiveSurveyButReplyInvalidFirstAnswer
· receiveSurveyButReturnFailedResponseForFirstQuestion
· receiveSurveyAndReplyButNotReturnResponseForLastQuestion
· receiveSurveyAndReplyButReturnFailedDeliveryReportForLastQuestion
· receiveSurveyButNotReplyAnyAnswer
同样地,在 Survey CAMPAIGN 测试中,所有由 Primitive Action & Primitive Verification 的组合都归类到 Action 中。
5 Cases
5.1 测试用例实现策略
5.1.1 测试用例编写原则
· 测试用例应该具有清晰的结构,调用 Data , Action 或 Verification 组成一个完整测试用例。测试用例看到的就是一个业务流程,而这些业务流程的描述是由若干个 Data , Action 或 Verification 。
· 测试用例的注释应该遵循 “Given…When…Then…Finally…” 的原则,也就是:
- Given for preparation or pre-condition
- When for test operation
- Then for test result verification
- Finally for test environment recover
· 测试用例按功能模块划分,具有相同功能的测试放到一个测试类中,而功能相关的测试类则放到同一个测试包中。
· 每个测试用例都必须是可读、可独立运行、可信赖的和可稳定运行的。在写测试用例的时候,需要连续运行测试类 5 次以上都成功才可以证明用例的稳定性。
· 每种类型的测试用例将会提供一个例子,供其他人写测试用例时参考。
5.1.2 测试用例组成流程图
以下是一个完整的测试用例的流程图:
5.2 Pull Campaign
Pull Campaign 的广告测试场景中,可以划分为广告流程测试场景和业务逻辑测试场景。
其中,广告业务流程测试场景有:
· WAPAdScenarioTest
· UssdAdScenarioTest
· PartialSmsAdScenarioTest
· NetworkAdScenarioTest
· HouseAdScenarioTest
· ApplicationAdScenarioTest
· RingBackAdScenarioTest
业务逻辑测试场景有:
· PullCampaignTargetingScenarioTest
· PullCampaignFilteringScenarioTest
· PullCampaignChargingScenarioTest
5.3 Push Campaign
在 PUSH CAMPAIGN 广告测试场景中,业务流程测试用例有:
· PushCampaignSMSAdSigScenarioTest
· PushCampaignSMSAdIpxScenarioTest
· PushCampaignSMSAdHubScenarioTest
· PushCampaignMMSAdSigScenarioTest
· PushCampaignMMSAdIpxScenarioTest
· PushCampaignMMSAdHubScenarioTest
业务逻辑测试用例有:
· PushCampaignTargetingScenarioTest
· PushCampaignFilteringScenarioTest
· PushCampaignChargingScenarioTest
5.4 Survey Campaign
在 Survey Campaign 广告测试场景中,业务流程测试场景有:
· SurveyCampaignSigScenarioTest
· SurveyCampaignHubScenarioTest
业务逻辑测试场景有:
· SurveyCampaignFilteringScenarioTest
· SurveyCampaignTargetingScenarioTest
6 Util
和所有的 JAVA 编码项目一样,在自动化测试框架中, Util 主要用来存放一些工具类。
7 例子
这一章,我们一起来看一下已经实现的几个例子。
7.1 Pull Campaign
以下是一个 Pull Campaign 自动化测试例子:
@Groups ( Groups . MAJOR )
@Test
public void fetchWapBannerAdAndClickToSite() {
//Given we get the campaign original budget before fetching a WAP Ad
String[] oldTotalDelivered = getBudget(getCampaign());
//And opt in one consumer
consumers = multiGenerateMinimalConsumerData (getOperatorData (). operatorId , 1);
optInConsumers ( consumers , webServicesConsumerCreator );
//And get the inventory id
InventoryData inv = getInventoryByChannel (getChannel());
//And set the Ad Type
setAdTypeParameter(AdTypeParameter. ADTYPE_BANNER );
//When fetch a WAP banner
fetchAd( consumers [0], inv.getInventoryId());
//And click WAP banner
clickAd();
//Then check transaction log
client .execute( new Wait(20));
int [] expectResponseCodes = { 2000, 4000 };
checkTransactionLog( consumers , expectResponseCodes, getChannel(), true );
//And check impression log
checkImpressionLog( consumers , true );
//And check click log
checkClickLog( consumers , true );
//And check budget
client .execute( new Wait(10));
checkBudget(oldTotalDelivered, inv.getInventoryId(), 1, false );
}
从这个例子,我们可以看到,测试用例呈现的是一个非常清晰的测试场景,它调用 Action 来完成测试步骤,调用 Verification 进行测试结果的检查。
7.2 Push Campaign
下面这个是 Push Campaign 自动化测试的例子:
@Test
@Groups ( Groups . MINI )
public void sendSmsAdToConsumerViaSIG() {
// Given total delivered budget
String[] oldTotalDelivered = getBudget(getCampaign());
// And opt in one consumer
consumers = multiGenerateMinimalConsumerData (getOperatorData (). operatorId , 1);
optInConsumers ( consumers , webServicesConsumerCreator );
// When check simulator
checkMessage( consumers );
// Then check transaction log
// Wait 20 seconds for 4000 log
client .execute( new Wait(20));
int [] expectResponseCodes = { 2000, 4000 };
checkTransactionLog( consumers , expectResponseCodes, getChannel(), true );
// And check impression log
checkImpressionLog( consumers , true );
// And check budget
client .execute( new Wait(10));
checkBudget(oldTotalDelivered, 1, false );
}