第三节 MVC应用程序架构和测试
在查看如何测试单个功能之后,您可能会问,整个Web应用程序如何? 如前所述,有以下级别的测试:
- 单元测试
- 集成测试
- 功能测试
在开始编写测试时考虑这一点很重要。 可能还有其他类型的测试,但现在让我们关注这三种测试。 在谈论Web应用程序时,您将需要所有这些测试,但不同的测试有不同的应用场景。
您可能知道,MVC的设计模式被许多Web应用程序和框架使用。model是存储所有业务(主)逻辑的部分。 您绝对应该使用单元测试覆盖主要业务逻辑,可能没有数据库交互或API调用。 这有时是PHP应用程序的问题; 业务逻辑等于数据库访问,这并不总是正确的。 一些抽象并不是一个坏主意,诸如对象关系映射(ORM)之类的东西以及诸如Doctrine ORM或Propel之类的系统在测试方面确实很有帮助。
作为起点,您应该编写简单的PHPUnit测试而不进行数据库交互,只是为了涵盖主要业务逻辑(例如,增值税计算)。
接下来我们要详细探讨的是集成测试。 当您访问数据库或调用API时,最好知道您的代码如何与另一个系统交互,如果您的实现匹配,另一方面发生了什么。
与单元测试相比,集成测试可能会很慢 - 您可能无法像单元测试那样经常运行它们。 如果您正在使用数据库,那么这取决于您设置测试的方式。 如果您正在处理已知的数据集和数据库结构,那么数据库结构可能会在您不知情的情况下发生更改(然后,由于更改的数据库结构而未更新的代码可能是一个非常严重的问题,因此测试失败可能会很好)。 如果您直接使用第三方API,则永远不会知道它何时会发生故障或更改。 但同样,立即知道某些事情不太正确可能会很好。
控制器不应包含任何业务逻辑。 如果他们这样做,它通常是非常丑陋的意大利面条代码,其中代码是重复的,不一致的,甚至可能充满了错误。 控制器应该只处理(分派)请求并发送响应。 理论上,您可以为它们编写单元测试,但通常使用MVC框架提供的单元测试支持。 由于您可以启动整个应用程序,以便能够测试控制器功能,因此您需要进行功能测试。 执行数百行甚至数千行代码来测试简单的请求/响应。
最后但并非最不重要的是一种观点。 视图应该只处理和显示输出; 没有其他的。 为了保持严格的MVC结构并在前端和后端开发人员之间划分工作,最好使用模板系统(如Twig或Smarty)进行查看。 使用普通的PHP,做很多事情是非常诱人的。 甚至可以测试视图,但通常只需通过控制器或Selenium等工具进行功能测试,直接在浏览器中运行黑盒测试。
在谈到MVC设计模式时,结论应该是单元测试应该关注模型,并且应该应用更严格的MVC模式。 代码将具有更好的质量,更容易测试,并且可能包含比讨厌的意大利面条代码更少的错误,其中控制器是一切的主人。 但是你可以测试控制器,而现代框架通常都有帮助器来允许你测试控制器。
测试控制器
要了解如何测试控制器,让我们看看一些最着名的PHP MVC框架提供的内容。 这只是一个简短的概述; 您可能需要官方文档才能确切了解每个框架提供的内容。
Zend Framework 1的测试可以如下面的代码片段所示:
<?php class Zf1Test extends Zend_Test_PHPUnit_ControllerTestCase
{
public function setUp ()
{
$this->bootstrap = array ( $this, 'appBootstrap' );
parent::setUp();
} public function testIndexActionShouldContainLoginForm ()
{
$this->dispatch( '/' );
$this->assertAction( 'index' );
$this->assertResponseCode( 200 );
$this->assertQueryContentContains( 'h1', 'Hello World!' );
}
}
Zend Framework 2的测试可以显示为以下代码片段:
<?php
namespace ApplicationTest\Controller; use Zend\Test\PHPUnit\Controller\AbstractHttpControllerTestCase; class Zf2Test extends AbstractHttpControllerTestCase
{
public function setUp ()
{
$this->setApplicationConfig( include
'/path/to/application/config/test/
application.config.php' );
parent::setUp();
} public function testIndexActionCanBeAccessed ()
{
$this->dispatch( '/' );
$this->assertResponseStatusCode( 200 );
$this->assertModuleName( 'application' );
$this->assertControllerClass( 'IndexController' );
$this->assertActionName( 'index' );
$this->assertQueryContentContains( 'h1', 'Hello World!' );
}
}
Symphony 2的测试显示在以下代码段中:
<?php
namespace Application\Tests\Controller; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; class IndexControllerTest extends WebTestCase
{
public function testIndex ()
{
$client = static::createClient();
$crawler = $client->request( 'GET', '/' );
$this->assertTrue( $client->getResponse()->isSuccessful() );
$this->assertGreaterThan( 0,
$crawler->filter( 'html:contains
("Hello World!")' )->count() );
}
}
测试控制器非常有用,例如,在编写API时。 API可以非常容易地进行测试,应该进行测试。 但是以这种方式测试控制器可能非常昂贵,因为每次测试都必须一次又一次地启动整个框架和应用程序,这需要时间和资源。 您可能很想采用这种方法,因为在启动完整的应用程序时,您拥有所有可用资源,包括与数据库的连接。
第三节 MVC应用程序架构和测试的更多相关文章
- [译]MVC应用程序生命周期
原文:MVC Application Lifecycle 来一探究竟在MVC应用程序中参与请求处理的各个不同组件. 目录: 序言 背景 UrlRoutingModule RouteHandler Mv ...
- 使用MVC 5、Web API 2、KnockoutJS、Ninject和NUnit开发、架构和测试Web应用程序
做一名微软软件开发人员就像在国际煎饼屋订早餐一样.每道菜都有一堆煎饼,你必须从各种各样的煎饼和糖浆口味中选择.对于web应用程序,解决方案堆栈是一组软件子系统或组件,用于交付功能完整的解决方案(无论是 ...
- 转: GUI应用程序架构的十年变迁:MVC,MVP,MVVM,Unidirectional,Clean
十年前,Martin Fowler撰写了 GUI Architectures 一文,至今被奉为经典.本文所谈的所谓架构二字,核心即是对于对于富客户端的 代码组织/职责划分 .纵览这十年内的架构模式变迁 ...
- Android 程序架构: MVC、MVP、MVVM、Unidirectional、Clean...
摘选自:GUI 应用程序架构的十年变迁:MVC.MVP.MVVM.Unidirectional.Cleanhttps://zhuanlan.zhihu.com/p/26799645 MV* in An ...
- GUI应用程序架构的十年变迁:MVC,MVP,MVVM,Unidirectional,Clean
十年前,Martin Fowler撰写了 GUI Architectures 一文,至今被奉为经典.本文所谈的所谓架构二字,核心即是对于对于富客户端的 代码组织/职责划分 .纵览这十年内的架构模式变迁 ...
- 测试驱动 ASP.NET MVC 和构建可测试 ASP.NET MVC 应用程序
[测试驱动 ASP.NET MVC] http://t.cn/8kdi4Wl [构建可测试 ASP.NET MVC 应用程序]http://t.cn/8kdi4Wj
- [渣译文] 使用 MVC 5 的 EF6 Code First 入门 系列:为ASP.NET MVC应用程序创建更复杂的数据模型
这是微软官方教程Getting Started with Entity Framework 6 Code First using MVC 5 系列的翻译,这里是第六篇:为ASP.NET MVC应用程序 ...
- [渣译文] 使用 MVC 5 的 EF6 Code First 入门 系列:为ASP.NET MVC应用程序实现继承
这是微软官方教程Getting Started with Entity Framework 6 Code First using MVC 5 系列的翻译,这里是第十一篇:为ASP.NET MVC应用程 ...
- ASP.NET MVC应用程序执行过程分析
ASP.NET MVC应用程序执行过程分析 2009-08-14 17:57 朱先忠 朱先忠的博客 字号:T | T ASP.NET MVC框架提供了支持Visual Studio的工程模板.本文 ...
随机推荐
- Yarn下Map数控制
public List<InputSplit> getSplits(JobContext job) throws IOException { long minSize = Math.max ...
- 学习vue-cli3的项目搭建
安装 关于旧版本 Vue CLI 的包名称由 vue-cli 改成了 @vue/cli. 如果你已经全局安装了旧版本的 vue-cli(1.x 或 2.x),你需要先通过 npm uninstall ...
- pycharm界面美化,个人喜欢
进入file-setting选项 界面设置主要是在appearance和editor里面.appearance主要是整个pycharm的主题设置,比如文件管理窗口的颜色,其实就是软件本身的主题设置.我 ...
- Logrotate实现Catalina.out日志每俩小时切割
一.Logrotate工具介绍 Logrotate是一个日志文件管理工具,它是Linux默认自带的一个日志切割工具.用来把旧文件轮转.压缩.删除,并且创建新的日志文件.我们可以根据日志文件的大小.天数 ...
- OpenLDAP部署目录服务
文档信息 目 的:搭建一套完整的OpenLDAP系统,实现账号的统一管理. 1:OpenLDAP服务端的搭建 ...
- ethereum(以太坊)(十一)--字节数组(一)
pragma solidity ^0.4.0; contract byte1{ /* 固定大小字节数组(Fixed-size byte arrays) 固定大小字节数组可以通过bytes1,bytes ...
- 【Effective C++读书笔记】序
C++ 是一个难学易用的语言! [C++为什么难学?] C++的难学,不仅在其广博的语法,以及语法背后的语义,以及语义背后的深层思维,以及深层思维背后的对象模型: C++的难学还在于它提供了四种不同而 ...
- python3.X中pickle类的用法(cPickle模块移除了)
1.python3.x中移除了cPickle模块,可以使用pickle模块代替.最终我们将会有一个透明高效的模块. 2.因为存储的是对象,必须使用二进制形式写进文件 #!/usr/bin/python ...
- PHP 多参数方法的重构
假设我们要完成一个保存文章的功能,如果采用函数编程的方式,大概会是下面这个样子: <?php function saveArticle($title, $content, $categoryId ...
- SQL_server_2008_r2和visual studio 2010旗舰版的安装(2013-01-16-bd 写的日志迁移
(以下操作是在Oracle VM virtualBox虚拟机中操作的,其实VMware Workstation 9虚拟机也挺不错的,不过用了很久的vmware想换个虚拟机用用 就暂时用Oracle V ...