阅读并接受单元测试,试图理解下面的帖子,解释了静态函数调用的艰辛.
我不清楚这个问题.我一直认为静态函数是一种在类中舍入实用函数的好方法.例如,我经常使用静态函数调用来初始化,即:
Init::loadConfig('settings.php');
Init::setErrorHandler(APP_MODE);
Init::loggingMode(APP_MODE);
// start loading app related objects ..
$app = new App();
Run Code Online (Sandbox Code Playgroud)
//阅读帖子后,我现在的目标是......
$init = new Init();
$init->loadConfig('settings.php');
$init->loggingMode(APP_MODE);
// etc ...
Run Code Online (Sandbox Code Playgroud)
但是,我为这堂课写的几十个测试是一样的.我什么都没改变,他们仍然都过去了.难道我做错了什么?
该职位的作者陈述如下:
静态方法的基本问题是它们是过程代码.我不知道如何对程序代码进行单元测试.单元测试假设我可以单独实例化我的应用程序.在实例化期间,我使用mocks/friendlies连接依赖项,这取代了真正的依赖项.使用程序编程没有任何"连线",因为没有对象,代码和数据是分开的.
现在,我从帖子中了解到静态方法创建了依赖关系,但是没有直观地理解为什么人们不能像常规方法那样容易地测试静态方法的返回值?
我将避免使用静态方法,但我想知道WHEN静态方法是否有用,如果有的话.从这篇文章看来,静态方法与全局变量一样邪恶,应尽可能避免.
关于该主题的任何其他信息或链接将不胜感激.
我在单元测试领域越来越深入.
我遇到的一个问题,就是我想要反馈的地方,就是当一个人运行多个测试套件时,也许只是我,但我需要使用参数--process-isolation来传递我的测试.我可以单独运行我的任何套件而没有任何问题,但是如果我在没有--process-isolation的情况下运行,那么运行我迄今为止在其中传播的180个断言的6-7套件会失败.问题是使用此参数使测试运行持续35分钟,而通常的2.5分钟.这是一个漫长的等待.
问题与使用模拟DI容器进行特定测试有关,并且当测试套件运行链接时,容器未正确重新初始化.在DI-Container上设置的静态属性用于测试预期的故障,使得以下套件中的测试失败.容器有一个参数,可以将包含的对象保存在静态var中,以便在每次调用时返回相同的实例.伪装的单身人士.这在应用程序级别上运行良好,这对测试来说只是一个麻烦.
我可以避免使用该容器参数并将应用程序编码为不使用静态属性,但是为了方法而避免使用有用的语言构造似乎有些过分.
也许我做错了什么(我当然希望如此!)但是我有一个印象,如果一个人想要在每个测试中以干净的状态运行SUT测试,那么就没有使用--process-isolation.这使得测试非常耗时并且可以稍微消除它的乐趣.我在编码时单独运行套件和测试,并在主要提交之前在后台运行套件,从而绕过了这个问题.
我正在经历的是正常的,有没有办法对付这个?你如何测试那里确保测试时间合理?如何处理静力学以免影响测试?
任何见解赞赏/评论赞赏.
这是一篇由这篇文章组成的通用虚构示例.考虑6个班级
TableFactory, TableData, TableCRUD, TableSchema, DBConnect, Logger.
Run Code Online (Sandbox Code Playgroud)
TableFactory
是外部类,假设它拥有TableData
DB表的对象.
在这里TableFactory
,没有呼叫TableSchema
或DBConnect
或logger
.我的目标是在外部范围内不需要的内部对象的示例.
TableData
是一个内部提取和操作数据,所以它需要TableCrud
,DBConnect
和Logger
.
TableCrud
包含TableSchema
和需要DBConnect
,和Logger
.
DbConnect
itseld,为了让事情变得有趣,需要一个Logger.我的例子现在是3个范围深.
我的问题非常简单,如果你有一个对象3(或更多)范围,外部范围内的对象没有调用,那么如何在不破坏接口隔离原则的情况下将这些对象从外部范围发送到内部范围 - > TableFactory shouldn不得不处理内部对象所需的DBConnect或Logger.
如果一个人尊重基本的OOP原则并且目标是易于测试 - >你将需要注入5个对象的外部对象,然后使用getter方法来传递链上需要的对象.而内部范围的对象反过来又要求注入其内部3范围深度对象的依赖关系,并为这些对象注入getter.这使得外部作用域对象需要许多依赖项,而getter只是为了传递它们.
是否有替代这种对象传递方法,我一路上错过了什么?请分享!任何链接/评论赞赏.
我需要在windows .bat文件中找出这个看似非常简单的问题.我过去10年一直在使用Linux全职,所以当谈到.bat脚本时,我处于相当陌生的境界.
我们有一些需要从这个.bat文件运行的单元测试,并且需要在运行测试后生成构建.
bat文件本身非常简单,我想只是链接命令:
cls
echo "Running test suite - CRMSync"
echo
echo
REM from command: --static-backup
phpunit --bootstrap test/bootstrap_test.php --verbose --log-junit
echo "Running phploc for CRMSync"
phploc --count-tests --verbose > C:\CRMsync\testResults\phploc\index.html
echo "Executing phing"
phing
Run Code Online (Sandbox Code Playgroud)
现在,除了没有通过phpunit命令执行任何操作之外,足够简单.我该如何处理?单元测试运行正常,但我怀疑它甚至可能在单元测试库中该进程被杀死.有没有办法以某种方式分叉进程或让下面的其他命令运行?
非常感谢SO'ers,任何帮助非常感谢.
也许我错过了一个细节,但我为单例_clone方法编写了一个小测试用例,但它没有在代码覆盖率报告中显示出来.
/**
* @covers ErrorHandling::__clone
*/
public function test__cloneNotCloneable(){
$class = new ReflectionClass('ErrorHandling');
$method = $class->getMethod('__clone');
self::assertTrue($method->isFinal(), '__clone method is not final.');
self::assertTrue($method->isPrivate(), '__clone method is not private.');
}
Run Code Online (Sandbox Code Playgroud)
__clone方法是常规(邪恶)单例的常用私有/最终__clone().
/**
* Define __clone as final and private to dissallow cloning.
*/
private final function __clone(){}
Run Code Online (Sandbox Code Playgroud)
我知道这可能是针对此的过度测试,但代码覆盖率报告是一种"做得好"的工作的图形表示.有没有办法在代码覆盖率报告中标记为此方法?
我已经开始重构一个小应用程序来使用一个小的DI容器,而不是使用$ registry :: getstuff(); 在我的课程中调用我将它们注入容器中.
这提出了两个问题,
Q1 - >我扩展了Pimple DI类并创建了一个容器,其中包含特定于需要DI的每个对象的依赖项.然后我将整个shebang对象提供给它,并在构造函数中将其解析为将DI的对象分配给我正在构建的对象的类属性.
我应该在新对象()调用中分离对象吗?我刚刚发现这样比较容易,但现在看到我是一个单人团队,我只想确认我有适当的方法.
Q2 - >我发现如果我在几个主要类上执行此操作,我遍布的$ registry对象将是无效的,这是否是使用DI的正常结果,没有更多的注册表?我可能在容器中注入了一个或两个单例,但它看起来就像我将需要的一样,甚至那些可以很容易地被淘汰,因为DI有一个share()属性,它返回对象的同一个实例,有效地消除了需要对于单身人士.这是摆脱应用程序需要注册表/单身人士的方式,因为如果它是这样的很容易.
我一直在花时间去理解编写可测试代码背后的方法,我偶然发现了Misko Hevery的一篇好文章,他清楚地解释了如何在应用程序构建中处理依赖关系,例如使用工厂加载所有对象,从而减少行使测试复杂化的依赖项
在他的帖子中,他提供了一个最小但尽管很有见地的例子,说明了他如何在java中设置应用程序,以下无耻地引用了以下内容:
// Your main should look like this:
class Main {
public static void main(String…args) {
AppFactory factory = new AppFactory(args);
MyApp app = factory.create();
app.run();
}
}
Run Code Online (Sandbox Code Playgroud)
然后他说:
请注意代码如何分为三个阶段.创建工厂,创建应用程序,运行应用程序 这使得它可以测试.无论你的应用是什么,你都应该放弃这种模式.为了让单例到正确的位置,Factory只创建一个实例,然后在调用new时将该实例传递给所有类的构造函数.请参阅:http://misko.hevery.com/2009/03/30/collaborator-vs-the-factory/
我不擅长Java,但是假设这可以在php中模仿,当然减去main()方法,但是在网络应用程序的上下文中$ args会来自哪里?和初始化?
我会非常有兴趣在PHP中看到一个最小的可测试应用程序示例,甚至是那些认为测试效率高的应用程序的链接.初始化是我很好奇的,主要是.我的目的不是复制粘贴,而是从经验丰富的OOP编码器提供的内容中学习.
我翻过几个流行代码库的代码:Zend,Symphony,但这些框架不是可运行的应用程序,看起来"太快太快",让我无法掌握清晰的画面.此外,在有关测试实践的框架中也指出了一些不足之处.只是一个小例子,如果可能的话(即使不可运行)会让我在从头开始创建一个小应用程序时更好地掌握正确的OOP代码布局实践.
我建立了一个小网站,以获得乐趣,熟悉bootstrap.
我遇到的问题是,无论我尝试什么,徽标图像都没有响应.
代码看起来很简单我相信我只是错过了一个小细节:
<div id="masthead">
<div class="container">
<div class="row">
<div class="col-md-7 header-logo">
<div class="header-logo" style="color: white;">
<img src="/img/gros_buck_175.png" class="img-responsive" align="left" style="padding-right: 1.5em;padding-top: 0px; max-width: 184px;">
<br>
TEL: 450 955-3422 <br>
182 CHEMIN D'ADAMSVILLE <br>
J2L 2Y6, BROMONT<br>
laboucheriedugrosbuck@gmail.com
<br clear="all">
</div>
</div>
<div class="col-md-5">
<div class="well well-lg">
<div class="row">
<div class="col-sm-12">
<img src="/img/sceau_140.png" class="img-responsive" align="left" style="padding-right: 1.2em;">
<h3 style="margin-top:0px; margin-bottom: 1em;">PROMO</h3>
FAITES VOTRE PLAN DE VIANDE:<br>
ACHETEZ POUR PLUS DE 100$ DE PRODUITS
À L'UNITÉ ET RECEVEZ 10% EN SAUCISSES. …
Run Code Online (Sandbox Code Playgroud) 在这里,我正在编写一个小应用程序,其唯一目的是获得更好的OOP /可测试代码习惯.爱它,顺便说一下!
我正在努力吸收开发"可测试代码"背后的方法,主要是通过阅读Sebastien Bergmann,Misko Hevery和Giorgio Sironi等单位测试福音传教士的帖子.
我所接受的困难之一是滥用静态方法,依赖于依赖于对象的对象的对象.目前,我被困在全球范围内.在我的应用程序开始时,我加载了一个CONSTANT,它只是在debug或prod中设置应用程序模式:
/**
* APP_MODE values:
*
* PROD Production, no errors displayed email sent on error, logs to
* logs/app-<date-time>.log.
*
* DEBUG: All warnings and errors displayed, emails disabled and log messages
* sent to console. Whether in-memory modifications to configuration
* data are allowed
*/
define("APPMODE", "DEBUG");
Run Code Online (Sandbox Code Playgroud)
如何根据此常量的状态测试应用程序类以进行正确的错误处理?
起初我的想法是简单地将全局常量移动到类常量而不是在我的init类中,这解决了这个特定类的情况,但我不满意这个过程.我的意思是,是否应该简单地避免在严格意义上的一个可能值总是不是"真正"常量的站点范围常量?
我无法想象测试人员必须为每个类编写2个测试套件,即initClassDebugTest.php和initClassProdTest.php,除非phpUnit可以某种方式重置全局状态?应该避免使用这种方式的全局常量吗?我有一种奇怪的直觉,我根本不应该使用常数.我很想知道测试savy编码器如何在运行时处理具有2个可能值的全局定义.
我很好奇其他人如何处理这个问题.写一个测试并不是那么糟糕,但嘲笑有点糟透了,削减了我的流量.是否可以拥有一个'fixtures'目录并且例如只用那个特定的模拟声明说mock_db.php?
更进一步,在函数中抽象出那些模拟是不好的做法?
即:
// function to include a db mock
include_once 'test/fixtures/dbmock.php';
$mockMYSQL = $dbmock('mysql', 'db1');
$mockMSSQL = $dbmock('mssql', 'db2');
Run Code Online (Sandbox Code Playgroud)
JUst有兴趣知道其他有经验的测试人员如何处理这个问题.我正在编写脚本来同步2个数据库,所以这个例子可能变得非常相关.