使用iTest做Service Testing

创建测试工程

创建新工程

命令行输入以下命令,创建一个基于iTest的示例工程。

mvn archetype:generate -B -DarchetypeGroupId=com.taobao.itest.archetypes

-DarchetypeArtifactId=itest-service-sample-archetype

-DarchetypeVersion=1.3-SNAPSHOT

-DarchetypeRepository=http://mvnrepo.taobao.ali.com/mvn/snapshots

-DgroupId=com.taobao.qatest

-DartifactId=mytestproject

该示例工程包含一些示例,略加修改就可以作为自己的测试工程。

已有工程引入iTest

如果已有的Maven工程需要引入iTest,在pom文件加入以下依赖。

com.taobao.test

itest

1.3-SNAPSHOT

test

创建BaseTestCase

创建自己的BaseTestCase继承com.taobao.itest.ITestSpringContextBaseCase

public class BaseTestCase extends ITestSpringContextBaseCase{

}

加载Spring配置文件

用@ITestSpringContext注解标注类来声明Spring上下文,itest会在测试运行时据此位置完成Spring上下文加载和缓存。

@ITestSpringContext({"/applicationContext-test.xml"})

public class BaseTestCase extends ITestSpringContextBaseCase{

}

注意“/applicationContext-test.xml“以”/“打头表明从classpath根目录开始寻址,对于Maven标准目录结构而言applicationContext-test.xml应位于src/test/resources目录下。

可以加载多个配置文件

@ITestSpringContext({"/applicationContext.xml","/applicationContext-test.xml"})

public class BaseTestCase extends ITestSpringContextBaseCase{

}

子类默认继承父类声明的配置文件

@ITestSpringContext({"/base-context.xml“})

public class BaseTestCase extends ITestSpringContextBaseCase{

}

@ITestSpringContext({"/extended-context.xml"})

public class ExtendedTest extends BaseTestCase {

}

通过设置@ITestSpringContext的inheritLocations属性为false,会屏蔽掉标注于父类的配置文件。

Spring Bean实例化

测试时需要用到在Spring配置文件中定义的Bean,只需在测试类里定义并用@Resource注解标注即可完成其实例化。

public class UserManagerTest extends BaseTestCase {

@Resource//用@Resource注解实例化bean(变量名跟配置文件中的bean id一致)

protected UserManager userManager;

}

数据加载管理

数据源配置

itest用Spring配置的数据源来加载数据文件,数据源类型无特殊要求,但建议用com.taobao.itest.jdbc.SchemaDataSource,itest会从效率等多方面考虑具体实现用哪个数据源。

生成测试数据文件

你可以通过各种方式创建自己的测试数据,这里只介绍如何通过工具将其生成为符合特定格式的XLS文件或XML文件,供@ITestDataSet在测试用例运行时加载。

String destFilePath = "src/test/resources/UserManagerTest.xls";//目的文件,如果后缀为xml则生成xml文件

DataSource dataSource = DbEnum.DEV_ARK.getDataSource("username");//数据源

//ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-datasource.xml");

//DataSource dataSource = (DataSource)applicationContext.getBean("db1");

String querySqls = "SELECT * FROM bmw_userlinks WHERE id IN(1102710301,1102710302) ;" + //多个语句用分号分隔

"SELECT * FROM tbd_forbid_words WHERE id=11054101011";

//将符合条件的记录生成为符合DbUnit数据格式的xls文件或xml文件(根据destFilePath的后缀决定)

DbUnitTools.generateDataSetFile(destFilePath, dataSource, querySqls);

测试数据加载与清理

默认加载

将上步生成的文件放到跟测试类同级classpath目录下,并用测试类来命名,对Maven标准目录结构,其位置关系如下:

src/test/java/

com/taobao/itest/sample/UserManagerTest.java

src/test/resources

com/taobao/itest/sample/UserManagerTest.xls

用@ITestDataSet注解标注测试类或方法,itest会在用例方法执行前加载数据到数据库,在用例方法执行完成后从数据库清理对应数据。

package com.taobao.test.sample;

@ITestDataSet

@ITestSpringContext({ "/datasource-test.xml" })

public class UserManagerTest extends BaseTestCase {

@Test

public void testGetGusets () {

...

}

@Test

public void testGetUsersByNick() {

...

}

@Test

public void testGetUsersByName() {

...

}

}

上例中itest从默认位置(相同classpath下跟类同名的xls文件)用默认数据源(在Spring配置文件中定义的唯一DataSource)用默认数据管理策略完成数据加载和清理。标注于类对该类所有的测试方法有效。

自定义数据文件位置

@ITestDataSet

@ITestSpringContext({ "/datasource-test.xml" })

public class UserManagerTest extends BaseCase {

@ITestDataSet("UserManagerTest_testGetUsers.xls")

@Test

public void testGetGusets () {

...

}

@Test

public void testGetUsersByNick() {

...

}

@Test

public void testGetUsersByName() {

...

}

}

上例中方法testGetGusets定义的@ITestDataSet覆盖了标注于类的@ITestDataSet,运行该方法时加载classpath:/com/taobao/itest/sample/UserManagerTest_testGetUsers.xls。 运行testGetUsersByNick和testGetGuestsByName这两个方法时将加载classpath:/com/taobao/itest/sample/UserManagerTest.xls。

自定义数据源名称

如果Spring上下文中有多个数据源,需指定DataSource名称。

package com.taobao.test.sample;

@ITestDataSet(dsNames="aDataSource")

@ITestSpringContext({ "/datasource-test.xml" })

public class UserManagerTest extends BaseCase {

}

多数据集多数据源情况

@ITestSpringContext({ "/datasource-test.xml" })

public class UserManagerTest extends BaseCase {

@ITestDataSet(locations = {"one.xls","another.xls"},dsNames={"aDataSource","bDataSource"})

@Test

public void testGetUsersOrderBy () {

}

上例中itest根据locations的dsNames定义的顺序,将用Spring Bean 名为”aDataSource“的数据源加载清理”one.xls“中的数据,用Spring Bean 名为”bDataSource“的数据源加载清理"another.xls"中的数据。

itest还提供用Excel的sheet名指定数据源,sheet名格式为dataSourceName.tableName。

自定义数据加载和清理策略

可用的策略及介绍如下

NONE:什么也不做

UPDATE :根据数据集内容更新表中数据

INSERT :将数据集内容插入表,可能会违反主键唯一约束

REFRESH :如果表中存在数据集中对应的数据则更新,不存在则插入

DELETE :从表中删除数据集中对应的内容

---------下面三条在公用数据库中慎用----------------------

DELETE_ALL :删除表中所有数据

TRUNCATE_TABLE:执行truncate table指令

CLEAN_INSERT :先执行DELETE_ALL,再执行INSERT

@ITestDataSet默认的策略是加载用”REFRESH“,清理用”DELETE“,通过指定@ITestDataSet的setupOperation和teardownOperation属性可以自定义策略。

@ITestDataSet(setupOperation="INSERT",teardownOperation="NONE")

public class UserManagerTest extends BaseCase {

@Test

public void testGetUsersByName() {

...

}

}

上面的例子中在执行前插入数据(若违反唯一索引抛异常),执行完成后选择不删除刚插入的数据。

支持无主键表

通常情况下,ITestDataSet根据数据库表主键完成插入和清理,有时候数据库表没有主键,在这种情况下使用ITestDataSet需要在excel里自定义主键。定义主键的方法很简单,在excel里将对应的字段名加下划线即可。

支持sysdate及sysdate加减天操作

有时我们希望插入的时间是动态的,当前时间或前后几天,这种情况在excel里把时间对应的字段值设置为sysdate表示动态替换为当前时间,设置为sysdate+n,或sysdate-n表示按当前时间加减n天(n为正整数,且1<=n<=31)

支持xml文件做为数据集

itest同样支持用xml做为数据文件,xml文件采用FlatXmlDataSet格式,可用前面介绍的DbUnitTools.generateDataSetFile工具生成xml文件,其格式示例如下

@ITestDataSet默认加载xls文件,如果要加载相同classpath目录下跟类同名的xml文件,需指定其fileType属性为xml。或者指定xml文件位置。

@ITestDataSet(fileType="xml")

public class UserManagerTest extends BaseCase {

@ITestDataSet("UserManagerTest_testGetUsers.xml")

@Test

public void testGetUsersByName() {

...

}

@Test

public void testGetUsersByNick() {

...

}

}

断言验证

itest推荐用junit4新断言语法assertThat结合Hamcrest来实现风格统一,精确表达测试思想的断言,并通过扩展org.hamcrest.Matchers结合unitils实现反射相关的断言。

使用时需在测试类里导入包

import static org.junit.Assert.*;

import static com.taobao.itest.matcher.Matchers.*;

下面是一些常用的示例

字符相关匹配符

/**equalTo匹配符断言被测的testedValue等于expectedValue,equalTo可以断言数值之间,字符串之间和对象之间是否相等,相当于Object的equals方法*/

assertThat(testedValue, equalTo(expectedValue));

/**equalToIgnoringCase匹配符断言被测的字符串testedString在忽略大小写的情况下等于expectedString*/

assertThat(testedString, equalToIgnoringCase(expectedString));

/**equalToIgnoringWhiteSpace匹配符断言被测的字符串testedString在忽略头尾的任意个空格的情况下等于expectedString,注意:字符串中的空格不能被忽 略*/

assertThat(testedString, equalToIgnoringWhiteSpace(expectedString);

/**containsString匹配符断言被测的字符串testedString包含子字符串subString**/

assertThat(testedString, containsString(subString) );

/**endsWith匹配符断言被测的字符串testedString以子字符串suffix结尾*/

assertThat(testedString, endsWith(suffix));

/**startsWith匹配符断言被测的字符串testedString以子字符串prefix开始*/

assertThat(testedString, startsWith(prefix));

一般匹配符

/**nullValue()匹配符断言被测object的值为null*/

assertThat(object,nullValue());

/**notNullValue()匹配符断言被测object的值不为null*/

assertThat(object,notNullValue());

/**is匹配符断言被测的object等于后面给出匹配表达式*/

assertThat(testedString, is(equalTo(expectedValue)));

/**is匹配符简写应用之一,is(equalTo(x))的简写,断言testedValue等于expectedValue*/

assertThat(testedValue, is(expectedValue));

/**is匹配符简写应用之二,is(instanceOf(SomeClass.class))的简写,*断言testedObject为Cheddar的实例 */

assertThat(testedObject, is(Cheddar.class));

/**not匹配符和is匹配符正好相反,断言被测的object不等于后面给出的object*/

assertThat(testedString, not(expectedString));

/**allOf匹配符断言符合所有条件,相当于“与”(&&)*/

assertThat(testedNumber, allOf( greaterThan(8), lessThan(16) ) );

/**anyOf匹配符断言符合条件之一,相当于“或”(||)*/

assertThat(testedNumber, anyOf( greaterThan(16), lessThan(8) ) );

数值相关匹配符

/**closeTo匹配符断言被测的浮点型数testedDouble在20.0??0.5范围之内*/

assertThat(testedDouble, closeTo( 20.0, 0.5 ));

/**greaterThan匹配符断言被测的数值testedNumber大于16.0*/

assertThat(testedNumber, greaterThan(16.0));

/** lessThan匹配符断言被测的数值testedNumber小于16.0*/

assertThat(testedNumber, lessThan (16.0));

/** greaterThanOrEqualTo匹配符断言被测的数值testedNumber大于等于16.0*/

assertThat(testedNumber, greaterThanOrEqualTo (16.0));

/** lessThanOrEqualTo匹配符断言被测的testedNumber小于等于16.0*/

assertThat(testedNumber, lessThanOrEqualTo (16.0));

集合相关匹配符

/**hasEntry匹配符断言被测的Map对象mapObject含有一个键值为"key"对应元素值为"value"的Entry项*/

assertThat(mapObject, hasEntry("key", "value" ) );

/**hasItem匹配符表明被测的迭代对象iterableObject含有元素element项则测试通过*/

assertThat(iterableObject, hasItem (element));

/** hasKey匹配符断言被测的Map对象mapObject含有键值“key”*/

assertThat(mapObject, hasKey ("key"));

/** hasValue匹配符断言被测的Map对象mapObject含有元素值value*/

assertThat(mapObject, hasValue(value));

反射相关匹配符

/**断言两个对象所有属性值相等*/

assertThat(JavaBeanObjectTested,propertiesEquals(JavaBeanObjectExpected));

/**断言两个对象指定属性值相等*/

assertThat(JavaBeanObjectTested,propertiesEquals(JavaBeanObjectExpected,property1,propertity2));

/**断言两个对象 除指定属性外其他属性值相等*/

assertThat(JavaBeanObjectTested,excludedPropertiesEquals(JavaBeanObjectExpected,property1,propertity2));

自动打印调用入参和结果

由于“Service Testing”的接口一般是JavaBean对象,通常包含N多的字段,测试时需要对相关字段赋值。有时(尤其是用例运行第一次失败时)需要知道调用的确切入参是什么,以检查构造测试数据是否正确,需要知道调用返回的确切结果是什么,以检查断言语句是否正确。

itest提供的LogInterceptor可以通过配置自动打印出调用入参和结果。LogInterceptor采用Spring Aop的思路实现,其配置示例如下

class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">

guestManager

logInterceptor

通过上面的配置为guestManager这个Bean注入了自动打印调用入参和结果功能。

package com.taobao.test.sample;

public class GuestManagerTest extends BaseCase {

@Resource

protected GuestManager guestManager;

@Test

public void testGetGusetsByName () {

Guest guest = populate (Guest.class);

List guests = guestManager.getGuests(guest);

}

}

执行上面的测试将会打印出类似下面的日志

GuestManagerTest.testGetGusets(33) |GuestManagerImpl.getGuests invoked with params:

param 1: com.taobao.testsupport.sample.model.Guest@1d47b2b[

id=

trackid=0a63263401ac269422217a09cc3

lastNick=James Gosling

]

GuestManagerTest.testGetGusets(33) |GuestManagerImpl.getGuests invoked result is:

[com.taobao.testsupport.sample.model.Guest@1700391[

id=88001

trackid=0a63263401ac269422217a09cc3

lastNick=James Gosling

]]

注意LogInterceptor的功能开启需要在log4j里设置com.taobao.itest日志级别为debug

Webx Testing

概述

“Webx”是阿里巴巴的web框架(wiki:http://code.taobao.org/trac/webx/wiki/ZhWikiStart ), “Webx Testing”的思路是通过Servlet为测试介入点,模拟Web容器,通过封装参数(url,request param,session,cookie等)完成对Web Module(Action/Screen)的调用,调用完毕可对Servlet中的对象(Rundata、Context)进行校验。下图展示了大致原理。

同样要说明的是,这里的“Webx Testing”跟传统的单元测试是不同的,“Webx Testing”不仅仅是测试Web层的Module(Action/Screen)逻辑代码,而是通过透传的方式测试到后面各个层,确保Web Module对外提供的功能正确性。相较于“Service Testing”,“Webx Testing”是更大集成情况下的测试,因此环境配置要比“Service Testing”复杂。

单元测试、“Service Testing”和“Webx Testing”到底搞哪个?答案是具体问题具体分析。一般来讲单元测试是开发人员必做的,有效的单元测试可以尽早的发现代码逻辑bug,减小集成测试失败的概率,对于bug的快速定位也非常有好处,但这个前提是单元测试的编写和执行要快,要成本低。如果时间紧又想收益高,建议开发人员做“Service Testing”,与单元测试要测每层每个细小的功能相比,“Service Testing”保证了整合起来的功能是能对外提供正确服务的,不仅仅覆盖了代码逻辑,还覆盖了各种用户使用场景(接口为谁服务,客户会怎么用)。如果有大量的业务/代码逻辑在Web层,那么“Webx Testing”是不错的选择,跟“Service Testing”相比,“Webx Testing”具有更大的覆盖率、更贴近上层业务需求、用例编写更容易等优势。

使用iTest-webx

创建测试工程

创建新工程

命令行输入以下命令,创建一个示例工程(如果是webx2修改下面命令中的itest-webx3-sample-archetype为itest-webx-sample-archetype))。

mvn archetype:generate -B -DarchetypeGroupId=com.taobao.itest.archetypes

-DarchetypeArtifactId=itest-webx3-sample-archetype

-DarchetypeVersion=1.3-SNAPSHOT

-DarchetypeRepository=http://mvnrepo.taobao.ali.com/mvn/snapshots

-DgroupId=com.taobao.qatest

-DartifactId=mytestproject

该示例工程包含一些示例,根据创建工程后的readme.txt说明略加修改就可以作为自己的测试工程了,但建议你了解细节。

已有工程引入itest-webx

如果已有的Maven工程需要引入itest-webx3,在pom文件加入以下依赖(如果是webx2修改下面的itest-webx3为itest-webx)。

com.taobao.test

itest-webx3

1.3-SNAPSHOT

test

itest-webx框架会自行依赖itest的匹配版本,因此不需要再引入itest。

创建BaseTestCase

创建自己的BaseTestCase继承com.taobao.itest.web.webx.ITestWebxBaseCase.

public class BaseTestCase extends ITestWebxBaseCase{

}

声明Web上下文

用@ITestWebContext注解标注于测试类声明web.xml文件的位置。

@ITestWebContext(webXml="target/petstore/WEB-INF/web.xml")//被测war包web.xml文件

public class BaseTestCase extends ITestWebxBaseCase{

}

模拟Web容器的类加载

用@ITestClassLoader注解标注与测试类,itest框架在运行时会根据该注解加载被测war包/WEB-INF/lib下的jar文件及classes目录下的文件。

@ITestClassLoader

@ITestWebContext(webXml="target/petstore/WEB-INF/web.xml")//被测war包web.xml文件

public class BaseTestCase extends ITestWebxBaseCase{

}

准备入参

iTest框架提供两种方式组织web请求入参,可结合使用。

编码方式

在准备入参前先想下完成某个web请求需要哪些类型的参数?最基本的我们需要url,需要参数,或许还需要Session和Cookie。这些都可以调用基类的方法实现。

setUrl(url) //设置要调用的url

addRequestParam(parameterName,parameterValue) //设置请求参数

addSessionParam(parameterName,parameterValue) //设置Session

addCookieParam(String parameterName,parameterValue)//设置Cookie

addFileParam(String parameterName,String filepath)//设置上传文件

addHeaderParam(String parameterName,String parameterValue)//设置Header

Webx框架对于表单参数会做特殊处理,比如业务上我们需要某个表单有phoneCode字段,开发会在form.xml里做类似配置

...

经Webx渲染到页面后phoneCode被转为_fma.b._0.pho,这样提交请求后传给服务端的实际参数名是_fma.b._0.pho,而不是phoneCode。

但我们测试时需要维护phoneCode这个可读性好的明文,对于这类表单参数的设置需调用基类的addGroupParam方法,iTest框架会在实际调用时做自动转换。

addGroupParam(groupName,parameterName,parameterValue)//设置表单参数

addGroupFileParam(String groupName,String parameterName,String filepath)//设置表单上传文件

配置方式

还可以把参数放在一个xml文件里

创建xml文件,以“测试类名+Param.xml”命名,放在跟测试类同名的classpath目录下。

src/test/java/

com/alibaba/sample/petstore/web/user/RegisterActionTest.java

src/test/resources

com/alibaba/sample/petstore/web/user/RegisterActionTestParam.xml

用@ITestWebParam标注于类自动装置输入参数

@ITestWebParam

public class RegisterActionTest extends BaseTestCase{

}

关于XML格式的详细信息可参考Web层测试入参XML详解,

下面是一个参考示例。

有些参数是多个测试类之间共享的,这类参数可以放到一个单独的xml文件里,以includes为根节点,下面可包含多个general节点。

引用公共文件参数的方式如下:

使用参数生成工具

“参数太多太杂,尤其是第一个用例,根本不知道该传哪些参数”,如果你也有这样的困惑,请使用itest-webx测试参数生成工具。

适用范围:对已开发完成的功能补webx测试

使用前置条件:会部署自己的应用在本地跑起来,知道对应的ear/war或部署目录的位置。

快速使用三部曲:

1. 下载工具包:访问http://itest.taobao.net:8088/fileadmin/?sort=1&dir=%2Fhome%2Fitest%2Ffiles%2Fitest-files 进入“itest-webx测试参数文件生成工具”,

下载itest-webx-tools.jar最新版本至本地目录,如d:盘

2. 处理部署包:打开cmd输入java -jar D:/itest-webx-tools.jar,根据提示输入应用的ear/war或部署目录位置。

3. 重启jboss,页面上走下对应的功能,在d:/itestXML生成itest-webx测试参数文件。

执行Web Module

执行Web Module非常简单,在测试方法(方法名在入参XML里定义)里调用基类的performWebModule()方法即可。

public class RegisterActionTest extends BaseTestCase{

@Test

public void testRegisterUserWithRightParam() throws MalformedURLException, IOException, Exception{

//执行被测Web Module(Action/Screen)

super.performWebModule();

}

}

验证

对数据库的验证跟其他层测试验证一样,对Action/Screen返回值的验证,基类对常用的验证点提供了方法供子类调用,这类方法以verify打头。

public class RegisterActionTest extends BaseTestCase{

@Test

public void testRegisterUserWithRightParam() throws MalformedURLException, IOException, Exception{

super.performWebModule();

//验证重定向

super.verifyRedirectLocation("http://localhost/user/register_account.htm");

//验证session内容

super.verifySessionHasKey("petstoreUser");

//验证DB内容

...

}

}

Web层测试入参XML详解

入参XML文件以tests为根节点,属性url为Action/Screen所对应的url。

以cookie、session和param节点定义不同类型的入参,这些节点可以被general节点和test节点包含。

general节点用于定义公用的参数被test节点引用。

test节点代表一个测试方法,其属性name的值跟测试方法名一致,可用include节点引用general节点定义的公共参数。

单个测试参数(cookie,session,param)

Web层的参数可大致分为cookie,session和request域的参数,分别用以下三类节点定义Action/Screen参数。每个节点有name和value两个必选属性,形成key-value对。desc节点是可选的,用于增强阅读性,程序不会引用到。 ?

cookie定义存放在cookie里的参数

session定义存放在session里的参数

param定义存放在request里的参数

上传文件(file)

表单参数

webx对表单参数会做特殊处理,这类参数需用group节点包含。

公用测试参数(general)

有些参数会被多个用例用到,为了减少重复,可以把这些参数抽取出来,供多个用例引用。我们用general节点将公用的参数包装起来,general节点有一个必选属性id,用于被测试用例test节点引用。

引用公用数据的标签为include,如include id=”login”/

测试用例/方法(test)

用test定义一个测试用例(方法)。test节点只有一个属性name,其值跟测试方法名相同。test节点可包含多个cookie、session、param节点。test节点还可包含多个include节点,引入general节点定义的参数。

测试类(tests)

每个测试类对应一个xml文件,tests为根节点,属性url为Action/Screen所对应的url。

tests节点可包含多个general节点和test节点

测试环境特定配置

执行“Service Testing”或“Webx Testing”时,大多数的配置文件不需要修改,部分配置需要修改或专门处理,如测试数据源和HSF服务。

测试环境数据源

如果数据源用到了Jndi,由于测试环境不支持Jndi,所以需要修改为测试用数据源,在Spring配置文件中按以下方式配置数据源(注意需将变量替代为实际值)

覆盖生产配置

“Service Testing”可以通过在单独的Spring配置文件里配置跟生产环境同名的Bean,用@ITestSpringContext将测试用配置文件后加载来达到覆盖生产环境Bean的目的。

@ITestSpringContext({"/applicationContext.xml","/applicationContext-test.xml"})

public class BaseTestCase extends ITestSpringContextBaseCase {

在上面的例子中,applicationContext-test.xml配置的Spring Bean会覆盖applicationContext.xml中同名的Spring Bean.

“Webx Testing”可以通过在src/test/config/WEB-INF目录下放置跟被测war包对应目录同名文件来达到覆盖生产环境配置的目的。

测试环境Hsf配置

如果用到了Hsf服务,按以下方式配置。 在pom文件中引入

com.taobao.hsf

hsfstarter

1.0.1-SNAPSHOT

test

com.taobao.hsf

hsfunit

1.0.1-SNAPSHOT

test

在src/test/resources目录下新建文件hsfconfig.properties,内容如下

hsf.server.port=12200

hsf.server.min.poolsize=10

hsf.server.max.poolsize=600

hsf.run.mode=1

hsf.client.localcall=true

在测试基类BaseTestCase里加上@ITestHsfStarter注解

@ITestHsfStarter(path="/home/admin/hsf",version="1.4.8.3")//启动hsf单测环境服务,请删除原来的static硬编码

public class BaseTestCase extends ITestWebxBaseCase {

运行时会检查指定目录是否存在hsf对应的版本,如果不存在,会自动下载,然后启动HSF服务。

itest考试切屏能检测出来吗_itest测试相关推荐

  1. js 实现在线考试切屏代码

    切屏定义:切换选项卡,切到其他程序,最小化窗口,分屏. 要求: 1.记录切屏间隔时间(切出去再切回来的时间差) 2.记录切屏次数 实现这个切换页面功能需要用到一个web的APIvisiblitycha ...

  2. welearn考试切屏会有显示吗_welearn视听说教程4答案截图

    welearn视听说教程4答案截图 来源:未知 作者:admin 人气: 发布时间:2020-09-28 摘要:welearn视听说教程4答案截图 更多相关问题 [单选] 下列属于中华人民共和国公民的 ...

  3. 智慧树考试复制粘贴会检测吗_智慧树考试可以分屏吗?切屏会被发现吗

    智慧树可以在线考试,有不少朋友想知道智慧树考试切屏有记录吗?智慧树考试分屏会被发现吗?下面小编就为大家带来相关介绍,感兴趣的朋友们快来一起了解下吧! -->>智慧树下载< 智慧树考试 ...

  4. 百一测评网站切屏检测绕过

    事情是这样的,这几天不是临近期末嘛,老师都开始划重点,准备在线考试的老师也在开始测试线上考试了,今天人工智能在百一测评发下来一套测试,想点进去看看能不能粘贴,结果刚出去百度,就弹出离开页面警告,这谁顶 ...

  5. 智慧树考试复制粘贴会检测吗_智慧树考试分屏会被发现吗

    全网最新活动请看下方内容或右侧内容! --------------- 智慧树是一款非常不错的学习的平台,里面有很多优质的学习资源和名师指导,大家可以在上面看直播学习,还可以和学霸名师互动,学习成果也可 ...

  6. python123网页版切屏_我能绕过各学习平台的切屏检测

    大家呢,都明白一个事--PC端搜题流程: 复制题目,接下来的操作我想到的有两种 ①切换浏览器选项卡,打件开某度,粘贴到某度的搜索框,然后回车. ②切换到某即时通讯软件,打开联系人"我的手机& ...

  7. vue3 切屏事件监听(考试防作弊)

    通过监听离开页面时时间戳和再次进来时的时间戳判断切屏时间,计算切屏次数 1.@vueuse npm i @vueuse/core import { ref, reactive, watch, onUn ...

  8. 科大讯飞考试系统怎么监考_科大讯飞的考试平台后台能检测出哪些内容?

    使用讯飞平台进行了多次测试,在仅使用网页端的情况下,关于切屏有如下要素.浏览器基于chrome内核. 1.切屏逻辑: 首先鼠标得在答题界面内,点击网页标签页以外的地方,如其他网页标签页.浏览器外的位置 ...

  9. 【杠精】切屏屏蔽和复制,怎么办--有方法解除移动切屏和复制网大限制

    来源:https://wangda.chinamobile.com //解除切屏限制 window.onmouseleave = window.onblur = window.onmouseout = ...

  10. 如何在笔试的时候绕开切屏提示

    今天惠风和畅,天气晴朗,我收到了一个笔试邀请. 是一个xxx(名字我就不说了)的网站制作的,他的编辑功能一言难尽,但是你却没有办法离开屏幕. 每次离开屏幕都会显示一个alert, 你说你在线环境做的不 ...

最新文章

  1. start.aliyun.com 正式上线!极速构建 Spring Cloud 应用
  2. spring boot2 修改默认json解析器Jackson为fastjson
  3. 面包好吃却五毒俱全,吃前请三思!
  4. Android NDK开发method GetStringUTFChars’could not be resolved
  5. STM32的ADC采样与多通道ADC采样
  6. JZOJ 3819. 【NOI2015模拟9.9】取石子
  7. 一份关于机器学习端到端学习指南
  8. 索引扫描时,对同一个叶子块访问多次的原因初探
  9. 垂直搜索引擎完整实现
  10. KBQA相关论文分类整理
  11. 多模态 | 从顶会论文看多模态预训练研究进展
  12. 【语音合成】基于matlab比例重叠相加法信号分帧与还原【含Matlab源码 561期】
  13. 【CC2530入门教程-01】CC2530微控制器开发入门基础
  14. pythondocx更新目录_使用Python更新MS Word .docx文档的目录(目录)
  15. 基于团队的持续优化之道
  16. [INFO1110课件讲解 一] USYD悉尼大学INFO1110 ED lessons Week1 课件 作业 assignment讲解
  17. java对象的内存布局
  18. 技术干货:工欲善其事,必先利其器 阿里云数据库系列谈之一
  19. 线上docker服务频繁自动重启解决过程
  20. 机器人砂型铸造_启东精密砂型铸造

热门文章

  1. mysql 只读_MySQL设置只读模式
  2. 显卡驱动与cuda、cudnn之间的关系
  3. ubuntu终端挂代理办法
  4. web服务器基于那个协议,网页浏览服务基于什么协议 Web服务器是基于什么协议...
  5. adb工具的安装方法
  6. C - Quick Sort (one of the simplest)
  7. 如何用服务器做虚拟主机,服务器如何搭建虚拟主机
  8. Vue_(基础)Vue中的事件
  9. 小象学院数据分析笔记:绘制常见的图形
  10. 苹果手机锁屏后无线重新连接服务器,iphone11锁屏自动断开wifi怎么办 苹果11手机热点自动断开解决方法...