为了账号安全,请及时绑定邮箱和手机立即绑定
3.3 使用 Swagger2 进行接口测试

此时我们启动项目,然后访问 http://127.0.0.1:8080/swagger-ui.html ,即可打开自动生成的可视化测试页面,如下图。Swagger2 自动生成可视化测试界面嗯,感觉这个页面简单整洁,直接给测试人员使用都很方便。我们以 update 方法为例演示下如何测试。先看看该方法的代码:实例: /** * 修改商品 */ @PutMapping("/goods/{id}") public void update(@PathVariable("id") long id, @RequestBody GoodsDo goods) { // 修改指定id的商品信息 goods.setId(id); goodsService.editGoods(goods); }测试时先选中对应的方法 update , 然后点击 Try it out 开始测试。Swagger2 生成的测试方法在参数区域输入 id 和 goods 的值。Swagger2 可视化测试参数输入点击 Execute 后,返回 Code 为 200 表示 http 请求成功!Swagger2 可视化测试结果输出由此可见, Swagger2 将接口以可视化的方式呈现出来,开发人员不必手输接口地址、参数名称,就可以发起测试并查看结果,确实非常方便。后端人员在开发完成后,可以自己使用 Swagger2 测试下接口可行性。而前端人员也可以打开 Swagger2 网页直接验证接口功能。

5.3 使用 Postman 测试 API 接口可用

后端开发完 API 接口后,需要先进行下简单测试以保证接口是正确可用的。我们可以使用 Postman 进行简单测试。启动 Spring Boot 项目后,使用 Postman 进行可视化测试,此处结果如下:测试查询商品信息测试查询商品列表测试新增商品测试修改商品测试删除商品

4.1 第一步:找到需要测试的接口

这一步很简单,只需要我们在浏览器中输入 Swagger 生成的 Swagger-UI 界面地址即可,在浏览器加载完毕后,我们可以在界面上看到我们项目中的所有接口,在这些接口列表中需要测试哪个接口,我们只需要点击接口名称即可,如下图所示:

5. 测试

我们直接编写测试类,对数据访问接口进行测试。此处通过 @FixMethodOrder(MethodSorters.NAME_ASCENDING) 注解,使测试方法按名称顺序依次执行。这样就可以一次性测试 GoodsDao 中的所有方法了,具体测试代码如下:实例:/** * GoodsDao测试类 */@SpringBootTest@FixMethodOrder(MethodSorters.NAME_ASCENDING) // 按方法名称顺序测试class GoodsDaoTest { @Autowired private GoodsDao goodsDao; /** * 新增一个商品 */ @Test void test_01() { GoodsDo goods = new GoodsDo(); goods.setName("手机"); goods.setPic("phone.jpg"); goods.setPrice("2000"); int count = goodsDao.insert(goods); assertEquals(1, count);// count值为1则测试通过 } /** * 更新商品信息 */ @Test void test_02() { GoodsDo goods = new GoodsDo(); goods.setId(1L); goods.setName("手机"); goods.setPic("phone.jpg"); goods.setPrice("3000"); int count = goodsDao.update(goods); assertEquals(1, count);// count值为1则测试通过 } /** * 获取商品信息 */ @Test void test_03() { GoodsDo goods = goodsDao.selectOne(1L); assertNotNull(goods);// goods不为null则测试通过 } /** * 删除商品 */ @Test void test_04() { int count = goodsDao.deletex(1L);//此处应为delete(1L) assertEquals(1, count);// count值为1则测试通过 } /** * 获取商品信息列表 */ @Test void test_05() { List<GoodsDo> goodsList = goodsDao.selectAll(); assertEquals(0, goodsList.size());// goodsList.size()值为0则测试通过 }}测试结果如下,说明所有测试都通过了。JUnit 测试结果

7. 测试

1. 语法jinja2 提供的 tests 可以用来在语句里对变量或表达式进行测试,语法如下:{% variable is test %}完整的 test 请参考 https://jinja.palletsprojects.com/en/master/templates/#builtin-tests,部分的 test 如下:test 名称功能defined变量是否已经定义boolean变量的类型是否是 booleaninteger变量的类型是否是 integerfloat变量的类型是否是 floatstring变量是否是 stringmapping变量的类型是否是字典sequence变量的类型是否是序列even变量是否是偶数odd变量是否是奇数lower变量是否是小写upper变量是否是大写2. jinja2 模板定义一个演示 test 功能的模板:<html>{% if number is odd %} <p> {{ number }} is odd{% else %} <p> {{ number }} is even{% endif %}{% if string is lower %} <p> {{ string }} is lower{% else %} <p> {{ string }} is upper{% endif %}</html>在第 2 行,number is odd 测试 number 是否为奇数;在第 8 行,string is lower 测试 string 是否为小写。3. jinja2 的模板输入number = 404string = 'HELLO'4. 渲染后的 html<html> <p> 404 is even <p> HELLO is upper</html>

4. 基于 Swagger-UI 界面的接口调试

调试的目的:我们都知道,在实际项目开发中,当我们的接口开发完毕之后需要进行一些必要的自行测试,目的就是来看看我们自己所开发的接口有没有低级错误和基本错误,在进行自测之前,我们先来了解一下什么是低级错误,什么是基本错误。低级错误一般是指接口的请求方法没有按照接口文档或者需求来规定,对外暴露的接口地址并不能被请求到。基本错误一般是指接口中的参数类型在开发时没有根据接口文档或者需求来定义,接口的返回数据中由于程序引起的返回空值或没有返回任何内容。调试的方法:在上述内容中,我们已经对 Swagger-UI 界面进行了基本详细的介绍。我们以一个用户登录接口为例,来看看如何在 Swagger-UI 界面上进行接口自测试。

4.3 Robot 测试框架

Robot Framework 是一个基于 Python 的,可扩展的关键字驱动的测试自动化框架,主要被用在测试驱动 (test-driven)类型的开发与验收中。Robot Framework 具有高度模块化的架构,用户通过编写 Python 脚本扩展功能,如下图所示:测试数据 (Test Data) 是简单、易于编辑表格格式启动 Robot Framework 时,它会处理测试数据,执行测试用例并生成日志和报告测试库 (Test library) 可以直接使用应用程序接口Robot Framework 具有如下优点:通过使用关键字驱动测试的方法,帮助测试人员创建具有可读性的测试用例,进而简化了整个自动化的过程。启用易于使用的表格语法,以统一的方式创建测试用例。提供易于阅读的结果报告和 HTML 格式的日志。提供一个简单的库 API,可以使用 Python 创建自定义测试库。

1.2 自动化测试

自动化测试是通过编写脚本的方式模拟手工测试的过程。通过运行脚本来执行测试用例,代替人工对系统的功能进行验证,从而节省了大量的人力。一切通过工具的方式来代替或辅助手工测试的行为都可以看做自动化,包括性能测试、接口测试等,但凡用到测试工具的测试都称为自动化测试。自动化测试得到广泛的应用,在招聘测试职位时,都需要自动化测试经验。在计算机专业招聘网站,以 “自动化测试” 作为关键字进行搜索,能够搜索到大量的职位,如下图所示:

2.7 系统测试

系统测试部分多以列表及表格为主。实例 7:# 第五章 系统测试## 5.1 功能点完成情况对照- [x] 数据库创建- [x] 后端开发- [x] 前端开发- [x] 接口联调- [ ] 日志归档## 5.2 测试结果| 功能点 | 是否测试 | 是否通过 | 备注 || ------------ | ---------------------------- | ---------------------------- | ---- || 登录 | <font color="green">√</font> | <font color="green">√</font> | 无 || 登出 | <font color="green">√</font> | <font color="red">×</font> | 无 || 增加学员信息 | <font color="red">×</font> | <font color="red">×</font> | 无 |其渲染效果如下:

4. 测试

我们主要是测试 JPA 模块正确可用,所以直接在测试类发起对 IGoodsDao 方法的测试即可。

2.6 测试

通过测试类发起测试,此处我们简单执行 1000 次插入,看看执行时间。需要注意的是,Spring Boot 进行测试时,需要添加注解 @SpringBootTest 。添加注解后该类可以直接通过 @Test 标注的方法发起单元测试,容器环境都已准备好,非常方便。实例:@SpringBootTest // 通过该注解,开启测试类功能,当测试方法启动时,启动了Spring容器class SpringBootHikariApplicationTests { @Autowired private DataSource dataSource;// 自动注入数据源 @Autowired private GoodsDao goodsDao; /** * 打印数据源信息 */ @Test // 测试方法 void printDataSource() { System.out.println(dataSource); } /** * 批量插入测试 */ @Test void insertBatch() { // 开始时间 long startTime = System.currentTimeMillis(); // 执行1000次插入 GoodsDo goods = new GoodsDo(); goods.setName("测试"); goods.setPic("测试图片"); goods.setPrice("1.0"); for (int i = 0; i < 1000; i++) { goodsDao.insert(goods); } // 输出操作时间 System.out.println("use time:" + (System.currentTimeMillis() - startTime)+"ms"); }}输出结果如下,可见默认数据源类型为 HikariDataSource ,插入 1000 条数据的时间大概为 1500ms (注意时间可能跟电脑性能等很多因素相关,此处只是进行简单的对比测试)。use time:1518mscom.zaxxer.hikari.HikariDataSource

2.4 执行测试

通常,PyCharm 通过运行已创建的运行/调试配置,以与其他应用程序相同的方式运行和调试测试。在许多情况下,也可以从上下文菜单启动测试会话,如果运行的测试没有永久运行/调试配置,则创建临时配置。然后,如果以后要重用,可以使用"运行/调试配置"对话框保存此类配置。1. 下面演示了不同运行路径,可运行整个模块,也可以运行单个方法。在 Run 工具 窗口内可以看到运行结果。工具窗口与通用的 Run 窗口基本一致,但会多一些为测试所加的工具按钮。2. 可以通过 Run 工具栏中 Rerun 与 Rerun Failed Tests 重新运行用例:3. PyCharm 可以设置自动重新运行测试的运行/调试配置(如果源代码已更改)。点击 Run 工具栏中的 Toggle auto-test 按钮该功能生效。下面只单独运行 test_area 这个方法,按下 Toggle auto-test,然后简单修改这个方法,会看到测试被自动执行了。

2.3 测试

我们在项目中与 main 目录同级的 test 目录中找到测试类 ZkClientDemoApplicationTests ,在其中添加测试方法。2.3.1 查询测试package cn.cdd.zkclientdemo;import cn.cdd.zkclientdemo.service.ZkClientServer;import org.I0Itec.zkclient.ZkClient;import org.junit.jupiter.api.Test;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import java.util.List;@SpringBootTestclass ZkClientDemoApplicationTests { // 依赖注入 @Autowired private ZkClientServer zkClientServer; @Test void contextLoads() { // 获取 ZkClient 对象 ZkClient zkClient = zkClientServer.getZkClient(); // 获取子节点集合 List<String> children = zkClient.getChildren("/"); System.out.println(children); // 释放资源 zkClient.close(); }}执行测试方法,控制台输出:[zookeeper, imooc]我们可以看到控制台输出了在上一节中我们增加的节点 imooc,说明我们的查询成功执行了。接下来我们测试其它的 API。2.3.2 创建持久节点创建持久节点测试:@Testvoid contextLoads() { ZkClient zkClient = zkClientServer.getZkClient(); // 在 imooc 节点下创建持久节点 wiki zkClient.createPersistent("/imooc/wiki"); // 获取 imooc 节点的子节点集合 List<String> children = zkClient.getChildren("/imooc"); System.out.println(children); // 释放资源 zkClient.close();}执行测试方法,控制台输出:[wiki]2.3.3 删除节点删除节点测试:@Testvoid contextLoads() { ZkClient zkClient = zkClientServer.getZkClient(); // 删除 imooc 的 子节点 wiki boolean delete = zkClient.delete("/imooc/wiki"); System.out.println(delete); // 释放资源 zkClient.close();}执行测试方法,控制台输出:truetrue 表示删除 wiki 节点成功。2.3.4 读写数据节点数据读写测试:@Testvoid contextLoads() { ZkClient zkClient = zkClientServer.getZkClient(); // 给 imooc 节点写入数据 wiki zkClient.writeData("/imooc","wiki"); // 读取 imooc 节点的数据 Object data = zkClient.readData("/imooc"); System.out.println(data); // 释放资源 zkClient.close();}执行测试方法,控制台输出:wikiTips: 当我们使用 API 操作节点时,节点参数必须是全路径。测试完成后,我们来对 ZkClient 常用的 API 做一下介绍。

4.2 PyTest 测试框架

Pytest 是一个第三方单元测试框架,比内置的 PyUnit 更简洁和高效,Pytest 主要特点有以下几点:简单灵活,容易上手,测试的可读性强支持参数化,可以细粒度地控制要测试的测试用例能够支持单元测试、集成测试、功能测试、接口测试多种类型Pytest 具有丰富的第三方插件,并且可以自定义扩展,例如如 pytest-selenium(集成selenium)、pytest-html(完美html测试报告生成)等可以很好的和 CI 工具结合,例如 jenkins与其它测试框架相比 Pytest 简单易学,举例如下:def add(a, b): return a + bdef sub(a, b): return a - bdef test_add(): assert add(1, 1) == 2def test_sub(): assert sub(2, 1) == 1定义了函数 test_add,它测试函数 add 的功能定义了函数 test_sub,它测试函数 sub 的功能运行 pytest ,发现所有名称以 test_ 为前缀的函数、并运行凭借着其开源和易学的特点,该工具被质量分析团队、开发团队、个人团队、以及各种开源项目广泛使用。许多大型互联网应用,如 Dropbox 和 Mozilla,均采用 Pytest。

1. PyCharm 支持的测试框架

测试框架可以组织、管理和执行那些独立的自动化测试用例,测试完成后统计测试结果。PyCharm 支持主流的测试框架,如图所示:前三种框架用的比较多,特别是 Pytest 近几年是比较流行的,经常与 request + Allure 搭档用于接口的自动化测试。另外,在基于业务驱动软件公司, BDD 测试框架应用也越来越广泛。大家可以根据自己的实际环境与需求所择合适的测试框架,有关安装及其它更详细信息,请参阅对应的框架文档。 图片来源:https://www.jetbrains.com/help/pycharm/testing-frameworks.htmlTips:在开始使用您选择的测试框架之前,请确保在计算机上安装了所需的框架。

3. Django 接口规范

对于 Django 的 URL 接口规范,遵循如下几点规则:开发之前,先要详细设计项目的 API 接口,包括输入参数以及响应数据的格式,最好能形成相关的接口文档;URL 接口要按照应用划分,每个 App 目录里面要有自己的 urls.py 文件。里面是本应用中的所有 url 和 视图的映射关系。总的 url 入口在 settings.py 文件中配置,默认是和 settings.py 文件同目录下的 urls.py;对于 URL 接口本身,倾向于使用 Restful 风格的 API 接口设计,比如接口:/manage/user:对应的 GET、POST、PUT 和 Delete 请求,我们往往会对应着用户模型 user 的增删改查操作这样的规范只是一种广泛使用的 API 接口设计风格,并不是必须的。因此在 Django 中的 各种 View 类来辅助我们设计这样的 API 接口。在项目中实现 Django 的 Web API 接口时,往往是使用 DFR (Django Rest Framework)来辅助构建项目的 API 接口。DRF 在 Django 的基础上迅速实现 API ,并且自身还带有 Web 的测试页面,可以方便的测试自己的 API 接口;最后就是关于公司内部接口设计人的喜好了,比如有人喜欢讲第一版本和第二版本接口设计用这样的 URL区分:https://example.com/api/v1/book/1 -> v1 版本接口https://example.com/api/v2/book/1 -> v2 版本接口还有设计响应数据的格式,也要简单明了。比如可以简单使用如下的 JSON 数据表示响应结果:{ "code": 200, # 响应码 "content": [] or {} or "", # 返回数据内容,可以是[]、{} or str等 "err_msg": "" # 错误信息}

4.8 多数据源测试

数据操作接口与对应的映射文件均已编写完毕,现在可以通过测试类进行多数据源测试了,我们在测试类中同时向两个库插入记录。实例:/** * 多数据源测试 */@SpringBootTestclass MultidbTest { @Autowired private OrderDao orderDao;// 对应数据源1 @Autowired private ErpOrderDao erpOrderDao;// 对应数据源2 /** * 插入测试 */ @Test void testInsert() { // 数据源1插入数据 OrderDo order = new OrderDo(); order.setCount(1L); order.setGoodsId(1L); int affectRows1 = orderDao.insert(order); // 数据源2插入数据 ErpOrderDo erpOrder = new ErpOrderDo(); erpOrder.setCount(order.getCount()); erpOrder.setGoodsId(order.getGoodsId()); erpOrder.setOutId(order.getId()); int affectRows2 = erpOrderDao.insert(erpOrder); assertEquals(1, affectRows1); assertEquals(1, affectRows2); }}运行测试方法后,两个数据库表中均新增数据成功,这样我们就成功的使用 Spring Boot 同时操作了两个数据源。

2.1 指定测试用例进行测试

其实每一项新的操作一般都会伴随一些问题产生。例如,我们在实际的开发过程中,有些时候只是改动了一处代码,但是如果直接执行 mvn test 命令的话,会将整个项目的测试用例全部都执行一遍,这对于我们来说,是有些得不偿失的,没必要因为一处改动,而去测试其他几十个或者几百个测试用例。那我们应该怎么办呢? 这里我们为了演示,写了两个测试类,OrderServiceTest 和OrderService2Test,其中第一个类中,有两个测试用例,第二个类中,只有一个测试用例。这时候,我们修改了第二个类中测试用例对应的方法,需要重新进行单元测试。我们可以直接执行命令:mvn test -Dtest=OrderService2Test:[INFO] Scanning for projects...[INFO][INFO] ----------------------< com.mic.tech:mall-order >-----------------------[INFO] Building mall-order 1.0.0-SNAPSHOT[INFO] --------------------------------[ jar ]---------------------------------[INFO] ...[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ mall-order ---[INFO] Surefire report directory: D:\code\mall-aggregate\mall-order\target\surefire-reports------------------------------------------------------- T E S T S-------------------------------------------------------Running com.mic.tech.OrderService2Test...Results :Tests run: 1, Failures: 0, Errors: 0, Skipped: 0[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time: 4.261 s[INFO] Finished at: 2020-05-21T22:17:47+08:00[INFO] ------------------------------------------------------------------------从结构来看,我们这里只执行了第二个测试类中的测试用例。

4.3 测试

由于之前已经通过注解 @EnableCaching 开启了缓存功能,此时我们直接运行测试类进行测试,输出结果如下:使用 Redis 缓存时控制台输出内容从上图输出结果可以看出,已经成功使用了 Redis 缓存管理器。另外我们可以直接使用 Redis 客户端查看生成的缓存信息,如下图已经有名为 GoodsCache::1 的缓存键存在了。Redis 客户端查看缓存信息

5.2 错误登录密码测试

调用登录接口,当密码不对时,返回登录失败提示信息。错误登录密码测试

3. 创建测试文件

现在,我们需要创建测试文件。通过右键点击我们的包名,弹出的菜单中并没有测试文件,所以,我们选择 Other…,如下图所示:在弹出的新建窗口中,我们直接在搜索框中输入 test,然后选择 Junit Test Case,如下图所示:点击 Nest 后,我们需要填写测试文件的名称,其实测试文件就是一个测试类,所以名称的命名应该和类名的命名规则一致,如下图所示:另外,在一步我们还需要选择使用的 Junit 版本,我们这里选择了目前最新的 Junit 5,也就是 New JUnit Jupiter test。点击 Finish 后,由于我们的项目还没添加 JUnit 5框架的 JAR 包,所以,Eclipse 会询问我们是否要现在添加,我们选择是即可,如下图所示:点击 OK 后,我们将可以看到 Eclipse 中新生成的测试文件 FirstTest.java,以及 Eclipse 帮我们导入的 JUnit 5 JAR 包,同时自动打开 FirstTest 类中也帮我们添加了一些默认代码,如下图所示:现在,我们以及准备好运行测试前的所有工作了。

3.6 测试

测试类代码同 spring-boot-hikari 一致,运行测试类后,结果如下:use time:1428mscom.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceWrapper

2.2 跳过测试

换到另外一个场景,构建项目的时候。在平时的开发过程中,我们经常会使用mvn package构建项目,但是如果这个项目比较庞大,测试用例会非常多,那么执行测试用例的过程就会非常耗时。那怎么办呢,test 阶段在 package 阶段之前,如果直接执行 package 阶段,test 阶段势必会被执行到。这个时候我们可以跳过测试来构建项目。(当然,这样的做法是不被建议的)在执行构建命令的时候,添加参数来指定跳过测试即可,mvn package -DskipTests 或者 mvn package -Dmaven.test.skip=true。这两个命令虽然都能够在构建项目的时候跳过测试,但还是有些区别的。-DskipTests: 会编译测试类;-Dmaven.test.skip=true: 不会编译测试类。

2.3 MultipartFile 接口

以字节数组的方式接收上传的文件数据,过于原始、低级,很难获取到文件的元数据。Spring MVC 提供有 MultipartFile 接口。查看 MultipartFile 接口源代码,可以知道 MultipartFile 接口提供了很多方法,能解析出上传文件的更多元数据,包括文件名、文件大小等,方便开发者更灵活地处理数据。public interface MultipartFile extends InputStreamSource { String getName(); @Nullable String getOriginalFilename(); @Nullable String getContentType(); boolean isEmpty(); long getSize(); byte[] getBytes() throws IOException; @Override InputStream getInputStream() throws IOException; default Resource getResource() { return new MultipartFileResource(this); } void transferTo(File dest) throws IOException, IllegalStateException; default void transferTo(Path dest) throws IOException, IllegalStateException { FileCopyUtils.copy(getInputStream(), Files.newOutputStream(dest)); }}MultipartFile 最常用的是 transferTo 方法,用来把上传文件存储到指定位置。重构上面的控制器代码。 @RequestMapping("/upload") public String upload(@RequestPart("upFile") MultipartFile file) throws IOException { String path = System.getProperty("webapp.root"); String filePath = path + "\\upload\\"+file.getOriginalFilename(); System.out.println(filePath); file.transferTo(new File(filePath)); return "success"; }如上面一样测试文件上传,结果没有什么不一样。

2.3 为测试文件配置 运行/调试 配置

前面的创建测试只是帮助我们创建了测试文件结构,具体的测试代码还是需要自己编写的。在进行配置之前,我们需要根据选择测试框架的规范编写测试代码。python unittest 文档参考, 修改上面自动生成的 test_rectangle.py 文件。from unittest import TestCasefrom rectangle import Rectangleclass TestRectangle(TestCase): def setUp(self): self.rectangle = Rectangle(30, 15) def test_area(self): area = self.rectangle.area() print(area) self.assertEqual(area, 450) def test_perimeter(self): perimeter = self.rectangle.perimeter() self.assertEqual(perimeter, 90) def test_diff(self): diff = self.rectangle.diff() self.assertEqual(diff, 15) def test_resize(self): self.assertRaises(ValueError, self.rectangle.resize, 15, 0) def tearDown(self): self.rectangle = None创建 运行/调试配置,有多种方式:直接点击 运行/配置 配置列表框打开对话框,类型选择 Unittests;Project 窗口选择文件, 右键上下文菜单选择 Create Name;在编辑器内,右键上下文菜单选择 Create Name。在配置过程中,可以指定测试范围,是模块、类甚至单个测试方法。

2.5 测试

为了充分理解缓存的含义,我们通过测试类发起测试。实例:@SpringBootTestclass SpringBootCacheApplicationTests { private Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired private CacheManager cacheManager; @Autowired private GoodsService goodsService; // 显示当前使用的缓存管理器类型 @Test void showCacheManager() { // 输出:org.springframework.cache.concurrent.ConcurrentMapCacheManager logger.info(cacheManager.getClass().toString()); } // 缓存测试 @Test void cacheTest() { // 第一次执行,没有缓存,执行方法体 goodsService.getById(1L); // 再次执行,直接取出缓存,不执行方法体 goodsService.getById(1L); // 移除缓存 goodsService.remove(1L); // 再次执行,已经没有对应缓存,所以执行方法体 GoodsDo oldGoods = goodsService.getById(1L); // 打印缓存内容 logger.info("old goods id:{} name:{}", oldGoods.getId(), oldGoods.getName()); // 更新缓存 GoodsDo temp = new GoodsDo(); temp.setId(1L); temp.setName("新的商品"); goodsService.edit(temp); // 查询并打印已更新的缓存内容 GoodsDo newGoods = goodsService.getById(1L); logger.info("new goods id:{} name:{}", newGoods.getId(), newGoods.getName()); }}我们查看下控制台输出如下,验证了我们设计的缓存机制。使用 Spring Boot 默认缓存时控制台输出内容

2.2 创建测试

创建一个新的 Python project,增加新文件 rectangle.py,添加下面的代码到文件, 继续沿用上一小节用到的待测代码。import mathclass Rectangle: def __init__(self, length, width, size=(40, 20)): self.length = length self.width = width self._size = size def area(self): area = self.length * self.width return area def perimeter(self): perimeter = (self.length + self.width) * 2 return perimeter def diff(self): diff = math.fabs(self.length - self.width) return diff def resize(self, width, height): if width <= 0 or height <= 0: raise ValueError("illegal size") self._size = (width, height) def get_length(self): return self.length def get_width(self): return self. width在编辑器中,将光标放在类声明或方法中的位置。从主菜单中,选择 Navigate -> Test。编辑器内,右键上下文菜单中选择 Go to -> Test (⌘⇧T: Ctrl + Shift + T)PyCharm 显示可用测试的列表。单击"创建新测试"。在打开 Create test 对话框中进行设置, 点击 OK 会自动生成测试文件 test_rectangle 与 测试方法模板。生成的模板 如下图所示: 没有像 unittest 那样创建同名测试类,无需像导入 unittest 一样导入pytest , 断言直接用 assert。使用pytest 写测试用例看上去更简单一些。

4.创建函数式接口对象

在上面,我们自定义了一个函数式接口,那么如何创建它的对象实例呢?我们可以使用匿名内部类来创建该接口的对象,实例代码如下:/** * 测试创建函数式接口对象 * @author colorful@TaleLin */public class Test { public static void main(String[] args) { // 使用匿名内部类方式创建函数式接口 FunctionalInterfaceDemo functionalInterfaceDemo = new FunctionalInterfaceDemo() { @Override public void run() { System.out.println("匿名内部类方式创建函数式接口"); } }; functionalInterfaceDemo.run(); }}运行结果:匿名内部类方式创建函数式接口现在,我们学习了Lambda表达式,也可以使用Lambda表达式来创建,这种方法相较匿名内部类更加简洁,也更推荐这种做法。实例代码如下:/** * 测试创建函数式接口对象 * @author colorful@TaleLin */public class Test { public static void main(String[] args) { // 使用 Lambda 表达式方式创建函数式接口 FunctionalInterfaceDemo functionalInterfaceDemo = () -> System.out.println("Lambda 表达式方式创建函数式接口"); functionalInterfaceDemo.run(); }}运行结果:Lambda 表达式方式创建函数式接口当然,还有一种更笨的方法,写一个接口的实现类,通过实例化实现类来创建对象。由于比较简单,而且不符合我们学习函数式接口的初衷,这里就不再做实例演示了。

5. 测试

启动项目后,我们使用 PostMan 进行验证测试。

8. 运行测试

终端中运行当前程序(与运行 Django 一样):python manage.py runserver此时,我们的 RESTful Web API 已构建完毕。由于我们是在本地测试,所以 API 域名部分采用本机地址。在浏览器地址栏输入 http://127.0.0.1:8000/api,即可看到当前项目中所有接口连接。点击链接 http://127.0.0.1:8000/api/students/ 即可前往学生信息接口,可以获取所有学生的信息,如下图所示:在页面底部的表单中,我们可以输入学生信息,点击 POST 按钮,即可实现向学生列表中添加新的学生信息:点击 POST 按钮后,返回如下信息:此时再点击 GET 按钮,我们发现上一步中添加的学生(小白)已经显示在所有学生信息中。在浏览器中输入网址 127.0.0.1:8000/api/students/2/,可以访问获取单个学生信息的接口(id 为 2 的学生),如下图所示:如果需要修改该学生的信息,可在页面底部表单中填写需要修改的信息,即可访问修改单个学生的接口。我们将小红年龄修改为 20:点击 PUT,返回如下页面信息,此时小红的年龄信息已经修改完毕:点击 DELETE 按钮,可以访问删除学生的接口:点 DELETE 后返回,如下页面,此时 id 为 2 的学生小红已被删除:

首页上一页1234567下一页尾页
直播
查看课程详情
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号