作为PHP开发人员,您可以使用测试驱动开发(TDD)技术通过编写测试来开发软件。 通常,TDD将开发的每个任务划分为各个单元。 然后编写测试以确保该单元的行为符合预期。

每个使用测试驱动开发的项目都重复执行三个简单步骤:

  • 为您要添加的下一功能编写测试。
  • 编写功能代码,直到测试通过。
  • 重构新旧代码以使其结构良好。

继续循环执行这三个步骤,一次进行一次测试,以建立系统的功能。 测试将帮助您进行重构,从而使您可以随着时间的推移改进设计,并使一些设计问题更加明显。

包含较小单个组件的测试称为单元测试 。 尽管可以独立执行单元测试,但是如果在将某些组件与其他组件集成时对其进行测试 ,则您正在执行集成测试 。 第三种测试是测试存根 。 测试存根允许您测试代码,而不必真正调用数据库。

为什么TDD有效

如今,由于您可能使用现代的PHP IDE语法,因此反馈已不是什么大问题。 开发的重要方面之一是确保代码能够实现您期望的功能。 由于软件很复杂(不同的组件相互集成),因此我们所有的期望都难以实现。 尤其是在项目结束时,由于您的开发,项目将变得更加复杂,因此更加难以调试和测试。

TDD验证代码是否按照您的预期进行。 如果出现问题,则仅需重新检查几行代码。 错误很容易发现和解决。 在TDD中,测试的重点是行为,而不是实现。 TDD提供了经过测试,设计和编码的行之有效的代码。

PHPUnit和Laravel

PHPUnit是用于单元测试PHP的事实上的标准。 从本质上讲,这是一个用于编写测试并提供运行测试和分析结果所需的工具的框架。 PHPUnit从Kent Beck的SUnit继承其结构和功能。

有几种不同的断言可以帮助您测试应用程序中各种调用的结果。 有时,您必须更有创造力才能测试更复杂的功能,但是PHPUnit提供的断言涵盖了您要测试的大多数情况。 以下是一些您将在测试中发现的更常见的列表 :

  • AssertTrue :检查输入以确认它等于true。
  • AssertFalse :检查输入以确认它等于假值。
  • AssertEquals :对照另一个输入检查结果是否匹配。
  • AssertArrayHasKey() :如果数组没有键,则报告错误。
  • AssertGreaterThan :检查结果是否大于一个值。
  • AssertContains :检查输入是否包含某个值。
  • AssertType :检查变量是否属于某种类型。
  • AssertNull :检查变量是否为空。
  • AssertFileExists :验证文件是否存在。
  • AssertRegExp :对照正则表达式检查输入。

默认情况下,Laravel中安装了PHPUnit 4.0,您可以运行以下命令对其进行更新:

composer global require "phpunit/phpunit=5.0.*"

Laravel根目录中的phpunit.xml文件使您可以进行一些配置。 在这种情况下,如果要覆盖默认配置,则可以编辑文件:

./tests/app/

如您在上面的代码中所看到的,我已经添加了样本(本文中未使用)数据库配置。

什么是教义ORM?

Doctrine是一个ORM,它实现数据映射器模式,并允许您将应用程序的业务规则与数据库的持久层完全分开。 要设置Doctrine,有一个桥梁可以与Laravel 5的现有配置匹配。 要在Laravel项目中安装Doctrine 2,我们运行以下命令:

composer require laravel-doctrine/orm

与往常一样,应将包作为服务提供者添加到app/config.php

LaravelDoctrine\ORM\DoctrineServiceProvider::class,

别名也应配置:

'EntityManager' => LaravelDoctrine\ORM\Facades\EntityManager::class

最后,我们发布带有以下内容的软件包配置:

php artisan vendor:publish --tag="config"

如何测试教义库

首先,您应该了解fixtures 。 夹具用于将受控数据集加载到数据库中,这是我们测试所需的。 幸运的是,Doctrine 2具有一个可帮助您为Doctrine ORM编写夹具的库。

要在我们的Laravel应用中安装灯具包,我们需要运行以下命令:

composer require --dev doctrine/doctrine-fixtures-bundle

让我们在tests/Fixtures.php创建夹具:

namespace Test;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\DataFixtures\FixtureInterface;
use app\Entity\Post;class Fixtures implements FixtureInterface
{/*** Load the Post fixtures* @param ObjectManager $manager* @return void*/public function load(ObjectManager $manager){$Post = new Post(['title'=>'hello world','body'=>'this is body']);$manager->persist($Post);$manager->flush();}
}

如您所见,您的灯具类应实现FixtureInterface并应具有load(ObjectManager $manager)方法。 Doctrine2固定装置是PHP类,您可以在其中创建对象并将其持久化到数据库中。 要在Laravel中自动加载灯具,我们需要在Laravel根目录中修改composer.json

..."autoload-dev": {"classmap": ["tests/TestCase.php","tests/Fixtures.php" //added here]},
...

然后运行:

composer dump-autoload

让我们在测试目录DoctrineTest.php创建测试文件。

namespace Test;
use App;
use App\Entity\Post;
use Doctrine\Common\DataFixtures\Executor\ORMExecutor;
use Doctrine\Common\DataFixtures\Purger\ORMPurger;
use Doctrine\Common\DataFixtures\Loader;
use App\Repository\PostRepo;class doctrineTest  extends TestCase
{private $em;private $repository;private $loader;public function setUp(){parent::setUp();$this->em = App::make('Doctrine\ORM\EntityManagerInterface');$this->repository = new PostRepo($this->em);$this->executor = new ORMExecutor($this->em, new ORMPurger);$this->loader = new Loader;$this->loader->addFixture(new Fixtures);}/** @test */public function post(){$purger = new ORMPurger();$executor = new ORMExecutor($this->em, $purger);$executor->execute($this->loader->getFixtures());$user = $this->repository->PostOfTitle('hello world');$this->em->clear();$this->assertInstanceOf('App\Entity\Post', $user);}
}

setUp()方法中,我实例化了ORMExecutor和Loader。 我们还将加载刚刚实现的Fixtures类。

不要忘记/** @test */批注非常重要,如果没有此注释,phpunit将返回No tests found in class错误中未No tests found in class

要在我们的项目根目录中开始测试,只需运行以下命令:

sudo  phpunit

结果将是:

PHPUnit 4.6.6 by Sebastian Bergmann and contributors.Configuration read from /var/www/html/laravel/phpunit.xml.
Time: 17.06 seconds, Memory: 16.00M
OK (1 test, 1 assertion)

如果要在灯具之间共享对象,则可以按名称轻松添加对该对象的引用,然后再引用该对象以形成关系。 这是一个例子:

namespace Test;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\DataFixtures\FixtureInterface;
use app\Entity\Post;class PostFixtures implements FixtureInterface
{/*** Load the User fixtures** @param ObjectManager $manager* @return void*/public function load(ObjectManager $manager){$postOne = new Post(['title'=>'hello','body'=>'this is body']);$postTwo = new Post(['title'=>'hello there ','body'=>'this is body two']);$manager->persist($postOne);$manager->persist($postTwo);$manager->flush();// store reference to admin role for User relation to Role$this->addReference('new-post',$postOne);}
}

和评论夹具:

namespace Test;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\DataFixtures\FixtureInterface;
use app\Entity\Post;class CommentFixtures implements FixtureInterface
{/*** Load the User fixtures** @param ObjectManager $manager* @return void*/public function load(ObjectManager $manager){$comment = new Comment(['title'=>'hello','email'=>'alirezarahmani@live.com','text'=>'nice post']);$comment->setPost($this->getReference('new-post')); // load the stored reference$manager->persist($comment);$manager->flush();// store reference to new post for Comment relation to post$this->addReference('new-post',$postOne);}
}

使用getReference()setReference()两种方法,可以在灯具之间共享对象。

如果灯具的订购对您很重要,则可以使用灯具中的getOrder方法轻松订购它们,如下所示:

public function getOrder(){return 5; // number in which order to load fixtures}

请注意,该顺序与Loader类相关。

关于固定装置的重要事情之一是它们解决依赖性问题的能力。 您唯一需要添加的是夹具中的方法,如下所示:

public function getDependencies(){return array('Test\CommentFixtures'); // fixture classes fixture is dependent on}

结论

这只是使用Laravel 5和PHPUnit进行测试驱动开发的描述。 测试存储库时,不可避免地要访问数据库。 在这种情况下,Doctrine装置很重要。

翻译自: https://code.tutsplus.com/tutorials/test-driven-development-with-laravel-doctrine--cms-25563

Laravel和Doctrine的测试驱动开发相关推荐

  1. 简单的11步在Laravel中实现测试驱动开发

    测试驱动开发(英语:Test-driven development,缩写为TDD)是一种软件开发过程中的应用方法,由极限编程中倡导,以其倡导先写测试程序,然后编码实现其功能得名. 下文是我在Mediu ...

  2. 在敏捷中应用测试驱动开发

    在敏捷和DevOps领域,企业越来越关注持续集成和持续部署问题.他们更频繁地更新软件,给软件测试造成额外的时间压力.而测试驱动开发可以成为解决这个问题的一剂良方. \\ 什么是测试驱动开发? \\ 测 ...

  3. 测试驱动开发 测试前移_测试驱动开发:它是什么,什么不是。

    测试驱动开发 测试前移 by Andrea Koutifaris 由Andrea Koutifaris Test driven development has become popular over ...

  4. 【软件测试】测试驱动开发

    TDD,测试驱动开发,从敏捷软件开发方法开始流行,是一种非常实用的质量保证执行方式.敏捷软件开发方法使得TDD流行起来. TDD的思想就是要在开发(设计和编码)应用程序代码(要测试的单元)之前,必须先 ...

  5. 测试驱动开发_DevOps之浅谈测试驱动开发

    "测试驱动开发(Test-Driven Development, TDD),以测试作为开发过程的中心,它要求在编写任何产品代码之前,先编写用于定义产品代码行为的测试,而编写的产品代码又要以使 ...

  6. 被高估了的测试驱动开发?

    测试驱动开发(TDD)始于上世纪 90 年代,时至今时今日,依然只有少数的开发者在践行着.本文作者从软件开发者的角度,又一次帮助我们定义了测试驱动开发,解答了众多开发着对 TDD 常见的谬误. 作者 ...

  7. C++ 测试驱动开发

    看到一篇非常好的C++测试驱动开发文章,这里转载下. 测试驱动开发(TDD)背景及综述 测试驱动开发是 Kent 提出的一种新的软件开发流程,现在已广为人知,这种开发方法依赖于极短重复的开发周期,面对 ...

  8. 面向 C++ 的测试驱动开发

    测试驱动开发(TDD)背景及综述 测试驱动开发是 Kent 提出的一种新的软件开发流程,现在已广为人知,这种开发方法依赖于极短重复的开发周期,面对开发需求,开发人员要先开发代码测试用例,这些代码实现的 ...

  9. 如何使用 Django 进行测试驱动开发,我来告诉你

    所谓测试驱动开发(TDD),就是先编写测试用例,然后编写代码来满足测试用例,具体包含以下步骤: 编写测试用例. 编写代码满足测试用例中的需求. 运行测试用例. 如果通过,说明代码满足了测试用例所定义的 ...

  10. servlet实现简单登录功能-基于测试驱动开发TDD

    今天学习了测试驱动开发(TDD)模式,用这个方法写一个简单的前端登录功能(基于servlet&Jsp的登录功能-三层架构实现) 不知道测试驱动开发,可以点这个: https://blog.cs ...

最新文章

  1. JSON序列化和反序列化还有这种玩法
  2. c语言手机通讯录退出程序,通讯录小程序(C/C++)C语言练习小程序
  3. java泛型方法 通配符_Java泛型教程–示例类,接口,方法,通配符等
  4. Win7下如何挂载NFS共享目录
  5. android glide 版本,Android Studio 第六十七期 - Android Glide3.7.0和3.8.0用法
  6. linux下创建只读账号,Linux只读账号配置
  7. vue 编辑弹框,编辑页面,列表数据也会跟着变
  8. Spring MVC中返回JSON数据的几种方式
  9. libvpx在windows下的编译
  10. 谈谈lucene的DocValues特性之SortedNumericDocValuesField
  11. apache服务器安装
  12. js实现批量下载文件
  13. Unity3D FPS帧数修改实现详解
  14. OpenCL: 从零开始学习OpenCL开发
  15. Java 数据类型(基本数据类型、引用数据类型)
  16. 【问题处理】Word修改页边距后,目录没有右对齐
  17. 内存压力测试 memtester移植到STM32
  18. ipconfig/all 实作
  19. Linux:压缩与解压命令大全(tar、gz、bz2、Z、zip、rar、lha、rpm、deb)
  20. 计算机保研科研经历——深度学习提问

热门文章

  1. 计算机管理 未分配磁盘,win7系统对未分配磁盘空间进行分区的操作方法
  2. SQL Server 2014下载及安装教程
  3. 有效括号 python_1111. 有效括号的嵌套深度
  4. Bluetooth LMP介绍
  5. linux桌面只运行浏览器,4个Linux桌面上的轻量级图像浏览器
  6. unity光照烘焙怎么弄
  7. access建立两个字段唯一索引_Mysql不止CRUD,聊聊索引
  8. 对数正态分布随机数c语言,在python中从对数正态分布生成随机数
  9. python_while 循环_珠穆朗玛峰
  10. Unity脚本组件勾选框的存在的意义