[英]How to display underlying tested method in PHPUnit tests?
I have test suites with lots of tests in them.我有测试套件,里面有很多测试。 here is a medium sized one:
这是一个中等大小的:
ok 4 - CommodityBasketTest::testStartsOutEmpty
ok 5 - CommodityBasketTest::testCanAddACommodity
ok 6 - CommodityBasketTest::testWillAddOneCommodityByDefault
ok 7 - CommodityBasketTest::testCannotAddACommodityWithAnNonNumericQuantity
ok 8 - CommodityBasketTest::testAddingTheSameCommodityWillIncreaseItsQuantity
ok 9 - CommodityBasketTest::testMultipleCommodityCanBeAdded
ok 10 - CommodityBasketTest::testTakingFromAnEmptyBasketWontWork
ok 11 - CommodityBasketTest::testTakesFirstCommodityFromTheBasket
ok 12 - CommodityBasketTest::testCanRetrieveASpecificCommodity
ok 13 - CommodityBasketTest::testWillThrowExceptionOnMissingCommodity
ok 14 - CommodityBasketTest::testReturnsZeroWorthForEmptyBaskets
ok 15 - CommodityBasketTest::testReturnsProperWorthOfACommodity
ok 16 - CommodityBasketTest::testWillAccuratelyReturnStatistics
How can I rig PHPUnit so that I can somehow display the underlying method being tested like I have it in the paste??如何安装 PHPUnit 以便我可以以某种方式显示正在测试的底层方法,就像我在粘贴中一样? I'm flexible on output;
我对 output 很灵活; I'd just like to know that
CommodityBasketTest::testReturnsZeroWorthForEmptyBaskets
tests CommodityBasket::getValuation()
, for instance.例如,我想知道
CommodityBasketTest::testReturnsZeroWorthForEmptyBaskets
测试CommodityBasket::getValuation()
。
This is what I'd like:这就是我想要的:
-- CommodityBasket::__construct() --
ok 4 - CommodityBasketTest::testStartsOutEmpty
-- CommodityBasket::add() --
ok 5 - CommodityBasketTest::testCanAddACommodity
ok 6 - CommodityBasketTest::testWillAddOneCommodityByDefault
ok 7 - CommodityBasketTest::testCannotAddACommodityWithAnNonNumericQuantity
ok 8 - CommodityBasketTest::testAddingTheSameCommodityWillIncreaseItsQuantity
ok 9 - CommodityBasketTest::testMultipleCommodityCanBeAdded
-- CommodityBasket::take() --
ok 10 - CommodityBasketTest::testTakingFromAnEmptyBasketWontWork
ok 11 - CommodityBasketTest::testTakesFirstCommodityFromTheBasket
ok 12 - CommodityBasketTest::testCanRetrieveASpecificCommodity
ok 13 - CommodityBasketTest::testWillThrowExceptionOnMissingCommodity
-- CommodityBasket::getValuation() --
ok 14 - CommodityBasketTest::testReturnsZeroWorthForEmptyBaskets
ok 15 - CommodityBasketTest::testReturnsProperWorthOfACommodity
-- CommodityBasket::dumpStats() --
ok 16 - CommodityBasketTest::testWillAccuratelyReturnStatistics
Thank you for your suggestions.谢谢你的建议。
My approach would be a combination of the @covers
Tag and a custom result printer .我的方法是结合使用
@covers
Tag 和自定义结果打印机。
You should use the @covers tag anyways to generate more meaningful code coverage, especially in bigger test suites it is important to make sure that only the tests that are supposed to test a method really generate coverage for it.无论如何,您都应该使用@covers 标签来生成更有意义的代码覆盖率,尤其是在更大的测试套件中,确保只有应该测试方法的测试才能真正为其生成覆盖率,这一点很重要。
I know your question isn't related to coverage but we'll get to that in a minute.我知道你的问题与报道无关,但我们会在一分钟内解决这个问题。 And maybe just using that annotation is enough for you as every method that doesn't have a test dedicated to it will show 0% coverage no matter if you run all your integration tests and so forth.
也许仅仅使用该注释对您来说就足够了,因为无论您是否运行所有集成测试等等,每个没有专门测试的方法都会显示 0% 的覆盖率。
The implementation can surly be tuned, i just wanted to produce something that works reasonably well to show of the concept and hopefully give you something you can adapt.实现可以很好地调整,我只是想制作一些可以很好地展示这个概念的东西,并希望给你一些你可以适应的东西。
The code is alpha as I've written it only for that question but it works with the current phpunit and I think i pasted everything you need.该代码是 alpha 代码,因为我只为该问题编写了它,但它适用于当前的 phpunit,我想我粘贴了您需要的所有内容。
--- myClass ---
-- myClass::a --
ok - myClassTest::testAone
fail - myClassTest::testAtwoFails
-- myClass::b --
ok - myClassTest::testB
-- myClass::untested --
!! Method untested !!
I hope this matches your desired output.我希望这符合您想要的 output。 The formatting can be changed rather easily in the code below.
在下面的代码中可以很容易地更改格式。
It prints this piece of information for every class you have a test for (an empty one is enough!)它为您测试的每个 class 打印这条信息(一个空的就足够了!)
If one tests @covers multiple methods it will show up for EVERY ONE of those methods如果一个测试 @covers 多种方法,它将显示在这些方法中的每一种
<?php
class myClass {
public function a() {
return 1;
}
public function b() {
return 2;
}
public function untested() {
return 3;
}
}
<?php
require_once("myClass.php");
class myClassTest extends PHPUnit_Framework_TestCase {
/**
* @covers a
*/
public function testAone() {
$sut = new myClass();
$this->assertSame(1, $sut->a());
}
/**
* @covers a
*/
public function testAtwoFails() {
$sut = new myClass();
$this->assertSame("error", $sut->a());
}
/**
* @covers b
*/
public function testB() {
$sut = new myClass();
$this->assertSame(2, $sut->b());
}
}
<phpunit>
<listeners>
<listener class="ResultPrinterListener" file="./ResultPrinterListener.php"></listener>
</listeners>
</phpunit>
<?php
class ResultPrinterListener implements PHPUnit_Framework_TestListener {
protected $suites = array();
public function addError(PHPUnit_Framework_Test $test, Exception $e, $time) {}
public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time) {}
public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time) {}
public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time) {}
public function startTest(PHPUnit_Framework_Test $test) {}
public function endTest(PHPUnit_Framework_Test $test, $time) {}
public function startTestSuite(PHPUnit_Framework_TestSuite $suite) {}
public function endTestSuite(PHPUnit_Framework_TestSuite $suite) {
$this->suites[] = $suite;
}
public function __destruct() {
$tests = array();
foreach($this->suites as $suite) {
foreach($suite->tests() as $test) {
if(!$test instanceOf PHPUnit_Framework_TestCase) {
continue;
}
$testClass = get_class($test);
$classUnderTest = substr($testClass, 0, -4); // just cutting the "Test" for now
/**
* Create an array structue
* array[ClassUnderTests][methodUnderTest][arrayOfTestMethodsThatTestThatMethod]
* Every method for a class you have at least one test for will show up here for now
*/
if(!isset($tests[$classUnderTest])) {
if(!class_exists($classUnderTest)) {
echo "\nCan't find matching class '$classUnderTest' for test class $testClass!\n";
}
$class = new ReflectionClass($classUnderTest);
foreach($class->getMethods() as $method) {
$tests[$classUnderTest][$method->getName()] = array();
}
}
$annotations = $test->getAnnotations();
if(!isset($annotations["method"]["covers"])) {
continue;
}
foreach($annotations["method"]["covers"] as $functionUnderTest) {
$statusLine = "";
$status = $test->getStatus();
if($status == PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE) {
$statusLine .= "fail - ";
} else if($status == PHPUnit_Runner_BaseTestRunner::STATUS_SKIPPED) {
$statusLine .= "skip - ";
} else if($status == PHPUnit_Runner_BaseTestRunner::STATUS_INCOMPLETE) {
$statusLine .= "inc - ";
} else {
$statusLine .= "ok - ";
}
$statusLine .= $testClass."::".$test->getName();
$tests[$classUnderTest][$functionUnderTest][] = $statusLine;
}
}
}
foreach($tests as $classUnderTest => $methods) {
echo "\n\n --- $classUnderTest --- \n\n";
foreach($methods as $method => $testCaseStrings) {
echo "-- $classUnderTest::$method -- \n";
if($testCaseStrings == array()) {
echo " !! Method untested !!\n";
continue;
}
foreach($testCaseStrings as $testCaseString) {
echo " $testCaseString\n";
}
echo "\n";
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.