单元测试框架(JUnit)
在很多情况下项目可能会很庞大,不可能每次都去完整地启动一个项目来测试某一个功能,这样显然会降低我们的开发效率,因此,我们需要使用单元测试来帮助我们针对于某个功能或是某个模块单独运行代码进行测试,而不是启动整个项目。
同时,在我们项目的维护过程中,难免会涉及到一些原有代码的修改,很有可能牵一发而动全身),而我们又不一定能立即察觉到,因此,我们可以提前保存一些测试用例,每次完成代码后都可以跑一遍测试用例,来确保之前的功能没有因为后续的修改而出现问题。
我们还可以利用单元测试来评估某个模块或是功能的耗时和性能,快速排查导致程序运行缓慢的问题,这些都可以通过单元测试来完成,可见单元测试对于开发的重要性。
①下载这两个jar包并添加为库:

②创建一个包并创建测试类

③类里面编写代码:(@Test是声明这是测试方法,并且方法里不能有参数,方法必须是public void)
package test; import org.junit.Assert; import org.junit.Test; public class MainTest { @Test public void method(){ System.out.println("我是测试用例"); Assert.assertEquals("错了",2,1); //断言表达式 } @Test public void method2(){ System.out.println("我是测试用例2"); } }
这个方法里可以直接点击运行并查看结果:




前置操作
希望在运行所有的测试之前进行的一个操作,使用@Before
package test; import org.junit.After; import org.junit.Before; import org.junit.Test; public class MainTest { @Before public void before(){ System.out.println("前置操作"); } @Test public void method(){ System.out.println("我是测试用例"); } @Test public void method2(){ System.out.println("我是测试用例2"); } @After public void after(){ System.out.println("收尾工作"); } }

JUL日志系统
之前使用的是System.out.println来打印信息,但是有些凌乱以及细粒度不够。比如希望项目只在debug时打印某些日志,实际运行不打印。在JDK自带的Logger在 java.util.logging.Logger 里。
主函数:
import java.util.logging.Logger; public class Main { public static void main(String[] args){ Logger logger =Logger.getLogger(Main.class.getName()); logger.info("我是一个日志信息"); } }

日志级别
最高级别是SERVE
- SEVERE(最高值)- 一般用于代表严重错误
- WARNING - 一般用于表示某些警告,但是不足以判断为错误
- INFO (默认级别) - 常规消息
- CONFIG
- FINE
- FINER
- FINEST(最低值
通过log方法调用不同的级别:
Logger logger =Logger.getLogger(Main.class.getName()); logger.log(Level.SEVERE,"严重错误");

例子:再来查看一个例子以及它的输出信息:
public class Main { public static void main(String[] args){ Logger logger =Logger.getLogger(Main.class.getName()); logger.log(Level.SEVERE,"严重错误",new InaccessibleObjectException("IO错误")); logger.log(Level.INFO,"普通信息"); logger.log(Level.CONFIG,"低于普通级别的信息"); } }

可以看到,低于普通级别的信息并没有被打印,因为现在日志级别是INFO,低于这个级别默认不打印。但是可以通过调低这个默认级别,这样就能打印低级别的log了。
设置日志打印信息级别
Logger logger =Logger.getLogger(Main.class.getName()); logger.setLevel(Level.ALL); //第一层:让logger放行 logger.setUseParentHandlers(false); //关闭原本的父类控制台处理器 ConsoleHandler hander = new ConsoleHandler(); hander.setLevel(Level.ALL); logger.addHandler(hander); //第二层:让处理器放行 logger.log(Level.SEVERE,"严重错误",new InaccessibleObjectException("IO错误")); logger.log(Level.INFO,"普通信息"); logger.log(Level.CONFIG,"低于普通级别的信息");

父日志处理器
Logger logger =Logger.getLogger(Main.class.getName()); System.out.println(logger.getParent().getClass());

文件处理器
不仅有控制台打印的日志处理器,还有写入到文件里面的文件处理器。
public class Main { public static void main(String[] args) throws IOException { Logger logger =Logger.getLogger(Main.class.getName()); logger.setLevel(Level.ALL); //第一层:让logger放行 logger.setUseParentHandlers(false); //关闭原本的父类控制台处理器 ConsoleHandler hander = new ConsoleHandler(); hander.setLevel(Level.ALL); logger.addHandler(hander); //第二层:让处理器放行 FileHandler fileHandler = new FileHandler("test.log"); fileHandler.setLevel(Level.ALL); // hander.setFormatter(new SimpleFormatter()); logger.addHandler(fileHandler); logger.log(Level.SEVERE,"严重错误",new InaccessibleObjectException("IO错误")); logger.log(Level.INFO,"普通信息"); logger.log(Level.CONFIG,"低于普通级别的信息"); } }

文件日志的格式
①可以看到,格式上它是XML文件形式,这是因为默认情况下文件日志就是这个格式,可以设置
hander.setFormatter(new SimpleFormatter());使得输出内容和控制台格式一样:

②也可以通过设置 hander.setFormatter(new XMLFormatter()); 使得控制台输出的是XML格式:

③也可以自定义日志的格式。
追加文件日志
只需要在参数上增加一个true的参数,就可以在原来的日志上进行追加而不是重写
FileHandler fileHandler = new FileHandler("test.log",true);
过滤器
日志可以设置一个过滤器,比如用hander设置,也可以用logger设置。
比如不管输入什么日志,都不会显示打印:
logger.setFilter(record -> false);
比如只会打印包含"普通"的信息;
logger.setFilter(record -> record.getMessage().contains("普通"));
logger.log(Level.SEVERE,"严重错误",new InaccessibleObjectException("IO错误"));
logger.log(Level.INFO,"普通信息");
logger.log(Level.CONFIG,"低于普通级别的信息");
