Api接口并行测试解决参数混乱问题ThreadLocal
import java.util.HashMap;
import java.util.Map;
public class ThreadLocalMapTest {
static ThreadLocal<Map<String, Object>> threadLocal = new ThreadLocal<Map<String, Object>>(){
@Override
protected Map<String, Object> initialValue() {
return new HashMap<String, Object>();
}
};
public static void main(String[] args) {
threadLocal.get().put("1","11");
dosomethings();
new Thread(new Runnable() {
@Override
public void run() {
threadLocal.get().put("1","22");
dosomethings();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
threadLocal.get().put("1","33");
dosomethings();
}
}).start();
}
private static void dosomethings() {
System.out.println(Thread.currentThread().getName() + " " +threadLocal.get());
}
}
解决线程并行参数混乱问题,使用ThreadLocal,将参数放到本次线程中
线程等待问题
线程是不等待的,等待实现方式
1.join 抢占cpu
2.sleep 释放CPU
3.线程计数器 CountDownLatch
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
class Thread1 extends Thread {
private CountDownLatch latch;
public Thread1(CountDownLatch latch) {
super();
this.latch = latch;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("run:"+Thread.currentThread().getName()+"_"+i);
}
latch.countDown();
}
}
public class ThreadTest {
public static void main(String[] args) throws Exception {
System.out.println("main start:"+Thread.currentThread().getName());
CountDownLatch latch=new CountDownLatch(10);
for (int i = 0; i < 10; i++) {
Thread1 thread1=new Thread1(latch);
thread1.start();
}
//最大等待时长XX
latch.await(1,TimeUnit.SECONDS);
System.out.println("main end:"+Thread.currentThread().getName());
}
}
线程计数器,设置等待的个数,执行一个线程减掉一个数,直到为0,才会执行下面的内容,同时也可以添加最大超时时间,超时不等;
jar工具包制做
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<!-- copy excel文件 -->
<resource>
<directory>${basedir}/data</directory>
<targetPath>${basedir}/target/data/</targetPath>
<!-- <includes> <include>*.xlsx</include> </includes> -->
</resource>
<!-- copy logs文件 -->
<!-- <resource> -->
<!-- <directory>${basedir}/logs</directory> -->
<!-- <targetPath>${basedir}/target/logs/</targetPath> -->
<!-- </resource> -->
</resources>
<finalName>apitest4</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<!-- 依赖包处理 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.8</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
<!-- 默认配置 compile 所有编译运行的包 除了test -->
<includeScope>compile</includeScope>
</configuration>
</execution>
</executions>
</plugin>
<!-- maven jar插件扩展 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<!-- lib依赖 包和main方法关系通过 MANIFEST.MF配置文件维护 -->
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.testfan.thread.ApiThreadTest</mainClass>
</manifest>
<!-- 自定义包 写入MANIFEST.MF -->
<manifestEntries>
<Class-Path>lib/checkpoint-0.0.1-SNAPSHOT.jar</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
<!-- maven 打源代码jar包 -->
<plugin>
<artifactId>maven-source-plugin</artifactId>
<version>2.1</version>
<configuration>
<attach>true</attach>
</configuration>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
点击pom.xml文件,run As 执行maven install,然后target文件下就打包了jar
切换到target文件,cmd运行命令java -jar xxx.jar
测试结果并行改串行
实现思路:先new 一个list,把一组测试用例测试结果放到局部list,然后放到全局list中
邮件发送
<dependency>
<groupId>commons-configuration</groupId>
<artifactId>commons-configuration</artifactId>
<version>1.10</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-email</artifactId>
<version>1.5</version>
</dependency>
config.properties 放到rescoures目录下
mail.host=smtp.163.com
mail.username=testfan_test2@163.com
mail.password=123456test
mail.title=12121212
mail.touser=90877407xx@qq.com,testfan_test2@163.com
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
public class PropertiesUtils {
private static Configuration config;
static {
if(null == config){
try {
config = new PropertiesConfiguration("config.properties");
} catch (ConfigurationException e) {
e.printStackTrace();
}
}
}
private PropertiesUtils(){}
public static String getString(String key){
return config.getString(key,"");
}
public static String[] getStringArray(String key){
return config.getStringArray(key);
}
public static void main(String[] args) {
String[] strs = getStringArray("mail.touser");
for (String string : strs) {
System.out.println(string);
}
}
}
import java.io.File;
import java.net.URL;
import org.apache.commons.mail.DataSourceResolver;
import org.apache.commons.mail.EmailAttachment;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.HtmlEmail;
import org.apache.commons.mail.ImageHtmlEmail;
import org.apache.commons.mail.resolver.DataSourceCompositeResolver;
import org.apache.commons.mail.resolver.DataSourceFileResolver;
import org.apache.commons.mail.resolver.DataSourceUrlResolver;
public class EmailUtils {
public static void main(String[] args) {
try {
// sendMsg();
String path= "D:\\result.xlsx";
sendEmailsWithAttachments("测试结果","请查收",path);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void sendMsg() throws Exception {
// HtmlEmail mail = new HtmlEmail();
ImageHtmlEmail mail = new ImageHtmlEmail();
// String htmlEmailTemplate = "这是一张用于测试的图片,请查收。 <img src=\"test.png\"> "
// + " <img src=\"http://commons.apache.org/proper/commons-email/images/commons-logo.png\">";
String htmlEmailTemplate = "这是一张用于测试的图片,请查收 "
+ " <img src=\"http://commons.apache.org/proper/commons-email/images/commons-logo.png\">";
// 解析本地图片和网络图片都有的html文件重点就是下面这两行;
// ImageHtmlEmail通过setDataSourceResolver来识别并嵌入图片
// 查看DataSourceResolver的继承结构发现有几个好用的子类
DataSourceResolver[] dataSourceResolvers = new DataSourceResolver[] { new DataSourceFileResolver(), // 添加DataSourceFileResolver用于解析本地图片
new DataSourceUrlResolver(new URL("http://")) };// 添加DataSourceUrlResolver用于解析网络图片,注意:new URL("http://")
// DataSourceCompositeResolver类可以加入多个DataSourceResolver,
// 把需要的DataSourceResolver放到一个数组里传进去就可以了;
mail.setDataSourceResolver(new DataSourceCompositeResolver(dataSourceResolvers));
String hostname = PropertiesUtils.getString("mail.host");
String password = PropertiesUtils.getString("mail.password");
String username = PropertiesUtils.getString("mail.username");
String[] toList = PropertiesUtils.getStringArray("mail.touser");
String subject = PropertiesUtils.getString("mail.title");
mail.setHostName(hostname); // 邮件服务器域名
mail.setAuthentication(username, password); // 邮箱账户
mail.setCharset("UTF-8"); // 邮件的字符集
mail.setFrom(username); // 发件人地址
for (String to : toList) {
mail.addTo(to); // 收件人地址,可以设置多个
}
mail.setSubject(subject); // 邮件主题
mail.setHtmlMsg(htmlEmailTemplate); // 邮件正文
String rString = mail.send(); // 发送邮件
System.out.println(rString);
}
public static void sendEmailsWithAttachments(String title, String context, String... filepath)
throws EmailException {
String hostname = PropertiesUtils.getString("mail.host");
String password = PropertiesUtils.getString("mail.password");
String username = PropertiesUtils.getString("mail.username");
String[] toList = PropertiesUtils.getStringArray("mail.touser");
// Create the email message
HtmlEmail email = new HtmlEmail();
email.setHostName(hostname); // 邮件服务器域名
email.setAuthentication(username, password); // 邮箱账户
email.setCharset("UTF-8"); // 邮件的字符集
// mail.setSSLOnConnect(true); // 是否启用SSL
// mail.setSslSmtpPort(sslSmtpPort); // 若启用,设置smtp协议的SSL端口号
email.setSubject(title);
email.setFrom(username); // 发件人地址
email.setHtmlMsg(context);
for (String to : toList) {
email.addTo(to); // 收件人地址,可以设置多个
}
// add the attachment
for (String fp : filepath) {
EmailAttachment attachment = new EmailAttachment();
attachment.setPath(fp);
attachment.setDisposition(EmailAttachment.ATTACHMENT);
attachment.setDescription("测试结果");
File f = new File(fp);
attachment.setName(f.getName());
email.attach(attachment);
}
// send the email
email.send();
}
}
log4j日志
<!-- slf4j 规范定义和桥架 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.25</version>
</dependency>
<!-- log4j2 实现 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.11.1</version>
</dependency>
将log4j2.xml放到resources目录下
<?xml version="1.0" encoding="UTF-8"?>
<!--设置log4j2的自身log级别为warn-->
<configuration status="warn">
<!-- 自定义变量 -->
<Properties>
<Property name="filedir">logs</Property>
</Properties>
<appenders>
<console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
</console>
<RollingFile name="RollingFileInfo" fileName="${filedir}/info.log"
filePattern="${filedir}/$${date:yyyy-MM}/info-%d{yyyy-MM-dd-HH-mm}-%i.log.gz">
<!-- 过滤规则-->
<Filters>
<ThresholdFilter level="INFO"/>
<!-- 更高级别的忽略 -->
<ThresholdFilter level="WARN" onMatch="DENY" onMismatch="NEUTRAL"/>
</Filters>
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<!-- 日志策略-->
<Policies>
<!-- 每天生成一个日志文件 -->
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
<!-- 限制单个文件大小 -->
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
<!-- 最大保存文件数 -->
<DefaultRolloverStrategy max="60" />
</RollingFile>
<RollingFile name="RollingFileWarn" fileName="${filedir}/warn.log"
filePattern="${filedir}/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log.gz">
<Filters>
<ThresholdFilter level="WARN"/>
<ThresholdFilter level="ERROR" onMatch="DENY" onMismatch="NEUTRAL"/>
</Filters>
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
</RollingFile>
<RollingFile name="RollingFileError" fileName="${filedir}/error.log"
filePattern="${filedir}/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log.gz">
<ThresholdFilter level="ERROR"/>
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
</RollingFile>
</appenders>
<loggers>
<root level="info">
<appender-ref ref="Console"/>
<appender-ref ref="RollingFileInfo"/>
<appender-ref ref="RollingFileWarn"/>
<appender-ref ref="RollingFileError"/>
</root>
</loggers>
</configuration>
测试类
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Log4JTest {
private static final Logger logger = LoggerFactory.getLogger(Log4JTest.class);
public static void main(String[] args) {
while(true) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
logger.debug("debug");
logger.info("info");
logger.warn("warn");
logger.error("error");
}
}
}
api整合
log4j2.xml文件具体详解