【发布时间】:2016-02-27 22:09:34
【问题描述】:
我正在将 Symfony 2.8(最新)用于 Web 应用程序,其中可以单独使用/重用的应用程序的每个部分都是一个自己的包。例如有一个 NewsBundle、GalleryBundle、ContactBundle、AdminBundle(这是一个特例——它只是一个用于收集特定包提供的特征的 EasyAdminBundle 的包装包)、UserBundle(FOSUserBundle 的子包,用于存储用户实体和模板)
我的问题基本上是,单元测试的最佳结构是什么?
让我再解释一下:在我的 UserBundle 中,我想对我的 FOSUserBundle 实现进行测试。我有一个方法测试登录页面(通过 HTTP 状态代码)、登录失败(通过错误消息)、登录成功(通过特定代码元素)、记住我(通过 Cookie)、注销(通过页面-内容)
<?php
namespace myNamespace\Admin\UserBundle\Tests;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
/**
* Class FOSUserBundleIntegrationTest.
*/
class FOSUserBundleIntegrationTest extends WebTestCase
{
/**
* Tests the login, login "remember-me" and logout-functionality.
*/
public function testLoginLogout()
{
// Get client && enable to follow redirects
$client = self::createClient();
$client->followRedirects();
// Request login-page
$crawler = $client->request('GET', '/admin/login');
// Check http status-code, form && input-items
$this->assertTrue($client->getResponse()->isSuccessful());
$this->assertEquals(1, $crawler->filter('form[action="/admin/login_check"]')->count());
$this->assertEquals(1, $crawler->filter('input[name="_username"]')->count());
$this->assertEquals(1, $crawler->filter('input[name="_password"]')->count());
$this->assertEquals(1, $crawler->filter('input[type="submit"]')->count());
// Clone client and crawler to have the old one as template
$clientLogin = clone $client;
$crawlerLogin = clone $crawler;
// Get form
$formLogin = $crawlerLogin->selectButton('_submit')->form();
// Set wrong user-data
$formLogin['_username'] = 'test';
$formLogin['_password'] = '123';
// Submit form
$crawlerLoginFailure = $clientLogin->submit($formLogin);
// Check for error-div
$this->assertEquals(1, $crawlerLoginFailure->filter('div[class="alert alert-error"]')->count());
// Set correct user-data
$formLogin['_username'] = 'mmustermann';
$formLogin['_password'] = 'test';
// Submit form
$crawlerLoginSuccess = $client->submit($formLogin);
// Check for specific
$this->assertTrue(strpos($crawlerLoginSuccess->filter('body')->attr('class'), 'easyadmin') !== false ? true : false);
$this->assertEquals(1, $crawlerLoginSuccess->filter('li[class="user user-menu"]:contains("Max Mustermann")')->count());
$this->assertEquals(1, $crawlerLoginSuccess->filter('aside[class="main-sidebar"]')->count());
$this->assertEquals(1, $crawlerLoginSuccess->filter('div[class="content-wrapper"]')->count());
// Clone client from template
$clientRememberMe = clone $client;
$crawlerRememberMe = clone $crawler;
// Get form
$formRememberMe = $crawlerRememberMe->selectButton('_submit')->form();
// Set wrong user-data
$formRememberMe['_username'] = 'mmustermann';
$formRememberMe['_password'] = 'test';
$formRememberMe['_remember_me'] = 'on';
// Submit form
$crawlerRememberMe = $clientRememberMe->submit($formRememberMe);
// Check for cookie
$this->assertTrue($clientRememberMe->getCookieJar()->get('REMEMBERME') != null ? true : false);
// Loop all links on page
foreach ($crawlerRememberMe->filter('a')->links() as $link) {
// Check for logout in uri
if (strrpos($link->getUri(), 'logout') !== false) {
// Set logout-link
$logoutLink = $link;
// Leave loop
break;
}
}
// Reuse client to test logout-link
$logoutCrawler = $clientRememberMe->click($logoutLink);
// Get new client && crawl default-page
$defaultPageClient = self::createClient();
$defaultPageCrawler = $defaultPageClient->request('GET', '/');
// Check http status-code, compare body-content
$this->assertTrue($defaultPageClient->getResponse()->isSuccessful());
$this->assertTrue($logoutCrawler->filter('body')->text() == $defaultPageCrawler->filter('body')->text());
}
}
所有这些测试都将在一种方法中完成,因为如果我用不同的方法进行测试,我将有大量(5x4 行 = 20 行复制和粘贴)重复代码。这是否遵循最佳实践?分离单元测试的最佳实践是什么? (或其他措辞:你会怎么做?)
问题的第二部分:是否有可能为测试类或类似的东西提供辅助功能?我的意思是提供登录客户端的示例方法。这将是管理功能测试所需要的。
【问题讨论】:
-
为什么评价这么差?我该怎么做才能使我的问题变得更好?
-
因为这个问题非常广泛,大多是基于意见的,并且没有明确的答案。您可能想要一个更具体的问题,其中包含一些您尝试过的代码示例。
-
我已经添加了我当前的代码并稍微更新了文本。你是对的,这可能是基于意见的,但我没有找到关于如何管理代码的“最佳实践”。这将帮助我从社区经验中受益,因为这里有许多专业的开发人员。
标签: php unit-testing symfony