热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

PHPUnit测试问题-如何对我的班级进行单元测试-PHPUnitTestQuestion-HowtoUnittestmyclass

ImtryingtogetintoUnittestingfortheobviouspositivesitintroduces,andImtryingtowrite

I'm trying to get into Unit testing for the obvious positives it introduces, and I'm trying to write a Unit test for a class I wrote the other day. (I know this is the opposite to TDD, please bear with me)

我正试图进行单元测试,看看它引入的明显积极因素,我正在尝试为前几天写的一个类写一个单元测试。 (我知道这与TDD相反,请耐心等待)

My class, Image, is used in conjunction with some others for image manipulation.

我的课程,Image,与其他一些人一起用于图像处理。

Image essentially wraps a GD image resource and stores data along with it. For example, an instance of Image will always contain it's current state, i.e. its new width/height if resized, the original image data, etc.

Image实际上包装了GD图像资源并随之存储数据。例如,Image的一个实例将始终包含它的当前状态,即调整大小时的新宽度/高度,原始图像数据等。

The Image class also contains methods for,

Image类还包含方法,

  • Creating itself from a file, string data, or URL, e.g. $image->loadFromPath()
  • 从文件,字符串数据或URL创建自己,例如$图像 - > loadFromPath()

  • Creating a new GD image resource from the properties of the current Image instance, e.g. for image resizing to maintain background transparency, etc.
  • 从当前Image实例的属性创建新的GD图像资源,例如用于调整图像大小以保持背景透明度等

  • Cloning the GD image resource for use in the manipulation classes
  • 克隆GD图像资源以在操作类中使用

What I'm struggling with is how to Unit test this class properly with PHPUnit. I've done some reading and I have a few conflicting ideas on how to approach it and I don't know what's right. Do I,

我正在努力的是如何使用PHPUnit正确地测试这个类。我已经完成了一些阅读,我对如何处理它有一些相互矛盾的想法,我不知道什么是正确的。我,我

  1. Write a test for each method of the class. I read somewhere that I should test each and every method. However, some of the methods run others (rightly so may I add), so you then have a chain of dependency. But I also read that each Unit test should be independent from the other. So what do I do if this is the case?
  2. 为每个类的方法编写一个测试。我在某处读到了我应该测试的每一种方法。但是,有些方法会运行其他方法(正确地说,我可以添加),因此您将拥有一系列依赖关系。但我也读到每个单元测试应该独立于另一个。那么如果是这样的话我该怎么办?

  3. Write each test as a usage route of the class. I also read somewhere that each test should instead represent 1 path/usage route you can take with the class. Therefore if you cover every usage, you'll ultimately get complete code coverage.
  4. 将每个测试写为类的使用路径。我还在某处读到,每个测试应该代表您可以在课程中使用的1个路径/使用路径。因此,如果您涵盖所有用途,您最终将获得完整的代码覆盖率。

So, which of these is correct, if any?

那么,哪些是正确的,如果有的话?

3 个解决方案

#1


9  

Unit tests should be written to evaluate the public interface of a class. Your test case should use the class as you intend it to be used in your program. The idea here is to test the behavior (either expected, unexpected, or edge conditions) of the class.

应编写单元测试来评估类的公共接口。您的测试用例应该使用该类,因为您打算在程序中使用它。这里的想法是测试类的行为(预期,意外或边缘条件)。

Both ideas you posted are correct. In theory, you should have enough test cases (routes through your code) that all your methods in the class are run.

您发布的两个想法都是正确的。理论上,您应该有足够的测试用例(通过代码的路由),以便运行类中的所有方法。

As was mentioned, 100% test coverage is a nice goal, but not always realistic.

如前所述,100%的测试覆盖率是一个很好的目标,但并不总是现实的。

Also, in the case of GD, be careful about writing unit tests that test GD's functionality (it's already been tested, you don't need to waste time testing it again). I would read up on using PHPUnit's mocks and stubs (and mocking the filesystem) in the PHPUnit manual.

此外,在GD的情况下,要小心编写测试GD功能的单元测试(它已经过测试,你不需要浪费时间再次测试它)。我会在PHPUnit手册中阅读使用PHPUnit的模拟和存根(以及模拟文件系统)。

Here's what an example test might look like:

以下是示例测试的样子:

public function testImageIsResized()
{
    $image = new Image();
    $image->loadFromPath('some/path');
    $image->resize(200, 300);
    $this->assertEquals(200, $image->getWidth());
    $this->assertEquals(300, $image->getHeight());
}

Now, depending on the expected behavior of the image class, this test might pass without issue, or it might fail because it was expecting the new dimensions to be proportionally constrained to the original image dimensions. But we did not explicitly call the internal method that checks for that constraint in the test itself.

现在,根据图像类的预期行为,这个测试可能通过没有问题,或者因为它期待新的尺寸成比例地限制原始图像尺寸也可能会失败。但是我们没有显式调用在测试本身中检查该约束的内部方法。

#2


5  

You can use the covers annotation to specify if a test covers multiple methods. So if one of your methods calls another method, you can simply add the annotation to the test's docblock and it will be added to your code coverage statistics, e.g.

您可以使用封面注释来指定测试是否涵盖多种方法。因此,如果您的某个方法调用另一个方法,您只需将注释添加到测试的docblock中,它就会被添加到您的代码覆盖率统计信息中,例如:

/**
 * @test
 * @covers MyClass::something()
 * @covers MyClass::_somethingElse()
 */
public function somethingWorksAsExpected()
{
    $this->assertSame($expected, $this->testObject->something());
}

For personal projects, 100% Code coverage is fine. However, I've seen talks at conferences where 100% are doubted to be necessary. Despite all the benefits, tests take time to write and in a budgeted project it might be sufficient to just test 80/20 and leave out uncritical low priority features of your app.

对于个人项目,100%的代码覆盖率是好的。但是,我在会议上看到过100%被怀疑是必要的会议。尽管有各种好处,但测试需要时间来编写,在预算项目中,仅测试80/20并省略应用程序的非关键性低优先级功能就足够了。

As for how to test your class, have a look at the chapter on Behaviour Driven Development in the PHPUnit Manual. In your case, I'd test the functionality you described in your question.

至于如何测试你的类,请参阅PHPUnit手册中关于行为驱动开发的章节。在您的情况下,我会测试您在问题中描述的功能。

#3


0  

Stephen Melrose said:

斯蒂芬梅尔罗斯说:

However, some of the methods run others (rightly so may I add), so you then have a chain of dependency. But I also read that each Unit test should be independent from the other

但是,有些方法会运行其他方法(正确地说,我可以添加),因此您将拥有一系列依赖关系。但我也读到每个单元测试应该独立于另一个

Test independence isn't about not testing the same code twice, it's about whether the result (or lack of result) of one test affects the result of another. If your first test inserts some data and then fails before it can remove that data, your second test might get different results than expected. Ideally you should be able to run your tests in a random order, or run some and not others.

测试独立性不是关于不测试相同代码两次,而是关于一个测试的结果(或缺少结果)是否会影响另一个测试的结果。如果您的第一个测试插入一些数据然后在它可以删除该数据之前失败,那么您的第二个测试可能会得到与预期不同的结果。理想情况下,您应该能够以随机顺序运行测试,或运行一些而不是其他运行。


推荐阅读
  • 本文探讨了如何利用HTML5和JavaScript在浏览器中进行本地文件的读取和写入操作,并介绍了获取本地文件路径的方法。HTML5提供了一系列API,使得这些操作变得更加简便和安全。 ... [详细]
  • 深入解析SpringMVC核心组件:DispatcherServlet的工作原理
    本文详细探讨了SpringMVC的核心组件——DispatcherServlet的运作机制,旨在帮助有一定Java和Spring基础的开发人员理解HTTP请求是如何被映射到Controller并执行的。文章将解答以下问题:1. HTTP请求如何映射到Controller;2. Controller是如何被执行的。 ... [详细]
  • 深入解析Spring启动过程
    本文详细介绍了Spring框架的启动流程,帮助开发者理解其内部机制。通过具体示例和代码片段,解释了Bean定义、工厂类、读取器以及条件评估等关键概念,使读者能够更全面地掌握Spring的初始化过程。 ... [详细]
  • 深入解析 Android IPC 中的 Messenger 机制
    本文详细介绍了 Android 中基于消息传递的进程间通信(IPC)机制——Messenger。通过实例和源码分析,帮助开发者更好地理解和使用这一高效的通信工具。 ... [详细]
  • 目录一、salt-job管理#job存放数据目录#缓存时间设置#Others二、returns模块配置job数据入库#配置returns返回值信息#mysql安全设置#创建模块相关 ... [详细]
  • 本文介绍如何在Spring Boot项目中集成Redis,并通过具体案例展示其配置和使用方法。包括添加依赖、配置连接信息、自定义序列化方式以及实现仓储接口。 ... [详细]
  • Redux入门指南
    本文介绍Redux的基本概念和工作原理,帮助初学者理解如何使用Redux管理应用程序的状态。Redux是一个用于JavaScript应用的状态管理库,特别适用于React项目。 ... [详细]
  • 微信小程序:授权登录与手机号绑定
    本文详细介绍了微信小程序中用户授权登录及绑定手机号的流程,结合官方指引和实际开发经验,提供了一套完整的实现方案,帮助开发者更好地理解和应用。 ... [详细]
  • ListView简单使用
    先上效果:主要实现了Listview的绑定和点击事件。项目资源结构如下:先创建一个动物类,用来装载数据:Animal类如下:packagecom.example.simplelis ... [详细]
  • 本文将详细探讨 Java 中提供的不可变集合(如 `Collections.unmodifiableXXX`)和同步集合(如 `Collections.synchronizedXXX`)的实现原理及使用方法,帮助开发者更好地理解和应用这些工具。 ... [详细]
  • 本文详细探讨了Java中的ClassLoader类加载器的工作原理,包括其如何将class文件加载至JVM中,以及JVM启动时的动态加载策略。文章还介绍了JVM内置的三种类加载器及其工作方式,并解释了类加载器的继承关系和双亲委托机制。 ... [详细]
  • 当unique验证运到图片上传时
    2019独角兽企业重金招聘Python工程师标准model:public$imageFile;publicfunctionrules(){return[[[na ... [详细]
  • 2017-2018年度《网络编程与安全》第五次实验报告
    本报告详细记录了2017-2018学年《网络编程与安全》课程第五次实验的具体内容、实验过程、遇到的问题及解决方案。 ... [详细]
  • 本文详细介绍如何使用CSS自定义HTML5视频播放器的样式,涵盖常见属性及跨浏览器兼容性问题。发布时间:2020-09-14 14:46:29;来源:亿速云;阅读量:58;作者:小新。 ... [详细]
  • CentOS 7.6环境下Prometheus与Grafana的集成部署指南
    本文旨在提供一套详细的步骤,指导读者如何在CentOS 7.6操作系统上成功安装和配置Prometheus 2.17.1及Grafana 6.7.2-1,实现高效的数据监控与可视化。 ... [详细]
author-avatar
清洁剂没看见家门口_200
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有