功能测试是一种质量保证(QA)过程和一种黑盒测试,其测试用例基于被测软件组件的规范。
您是否应该在 REST API 集成测试中使用另一个端点进行断言?
我有一个 REST API,我想为 POST 端点编写集成测试,这会在数据库中创建一个 Foo 项。在测试场景中,我向此 POST 端点发出请求。 在屁股里...
我知道功能测试用例和回归测试用例的定义。但我无法区分哪个测试用例应该属于功能测试,哪个测试用例应该属于回归测试。 例如...
在Smart Bear浮动许可证中,如何在InstallTestCompleteAdapter任务运行之前知道许可证可供用户使用?
如果是Smart Bear浮动许可证,在InstallTestCompleteAdapter任务运行之前如何知道该许可证可供用户使用? 我想知道浮动许可证是否可用...
下面的代码是我的Playwright测试函数 test("@Login @Testing 登录页面测试", async ({ page }) => { console.log("登录页面测试"); 常量
如何针对 API 运行 Webtestcase?关于功能测试的默认指南仅给出以下命令: $client = static::createClient(); $crawler = $client->request('GET', '/s...
我有一个库 C# 项目,其中编写了服务。这是使用 Serilog 并能够在正常执行期间在控制台上打印 Serilog。但是当我在功能测试中使用相同的库时
这是我的symfony项目,我正在其中练习功能测试,当我测试我的功能时出现这样的错误。 在这里,发生我的错误的代码部分:\ 这是我的 symfony 项目,我正在其中练习功能测试,当我测试我的功能时出现这样的错误。 这里,发生我的错误的代码部分:\ <?php namespace App\Tests; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use App\Entity\Category; class AdminControllerCategoriesTest extends WebTestCase { public function setUp():void { parent::setUp(); $this->client = static::createClient(); $this->entityManager = $this->client->getContainer()->get('doctrine.orm.entity_manager'); $this->entityManager->beginTransaction(); $this->entityManager->getConnection()->setAutoCommit(false); } public function tearDown():void { parent::tearDown(); $this->entityManager->rollback(); $this->entityManager->close(); $this->entityManager = null; //avoid memory leaks } public function testTextOnPage() { $crawler = $this->client->request('GET', '/admin/categories'); $this->assertSame('Categories list', $crawler->filter('h2')->text()); $this->assertContains('Electronics', $this->client->getResponse()->getContent()); } public function testNumberOfItems() { $crawler = $this->client->request('GET', '/admin/categories'); $this->assertCount(21, $crawler->filter('option')); } } 这里是我的.env,我有数据库连接: # In all environments, the following files are loaded if they exist, # the latter taking precedence over the former: # # * .env contains default values for the environment variables needed by the app # * .env.local uncommitted file with local overrides # * .env.$APP_ENV committed environment-specific defaults # * .env.$APP_ENV.local uncommitted environment-specific overrides # # Real environment variables win over .env files. # # DO NOT DEFINE PRODUCTION SECRETS IN THIS FILE NOR IN ANY OTHER COMMITTED FILES. # # Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2). # https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration ###> symfony/framework-bundle ### APP_ENV=dev APP_SECRET=018d7408d23791c60854cbb4fc65b667 ###< symfony/framework-bundle ### ###> doctrine/doctrine-bundle ### # Format described at https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url # IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml # # DATABASE_URL="sqlite:///%kernel.project_dir%/var/data.db" DATABASE_URL="mysql://root:@127.0.0.1:3306/symf5?serverVersion=mariadb-10.4.11" # DATABASE_URL="postgresql://symfony:[email protected]:5432/app?serverVersion=13&charset=utf8" ###< doctrine/doctrine-bundle ### 在这里,我的 .env.test 文件中有以下代码: # define your env variables for the test env here KERNEL_CLASS='App\Kernel' APP_SECRET='$ecretf0rt3st' SYMFONY_DEPRECATIONS_HELPER=999999 PANTHER_APP_ENV=panther PANTHER_ERROR_SCREENSHOT_DIR=./var/error-screenshots 我不知道出了什么问题,我尝试了不同的方法,但都不起作用,我也不知道这出了什么问题,该怎么办。希望你们能帮我解决我的问题。 谢谢! 您有两个选择: 为您的测试创建新数据库 删除数据库测试中的dbname_suffix,它负责为新数据库测试提供后缀名称 -at config/packages/test/doctrine.yaml - when@test: doctrine: dbal: # "TEST_TOKEN" is typically set by ParaTest dbname_suffix: '_test%env(default::TEST_TOKEN)%' 我想你可能忘记创建 .env.test 文件。 在文档中,您可以阅读需要此文件: https://symfony.com/doc/current/testing.html#customizing-environment-variables 在此文件中,您将使用正确的数据库进行测试。 告诉我它是否有效! 你的 phpunit.xml 看起来怎么样,或者你有吗? 我们在项目目录中添加了一个 phpunit.xml 并在 phpunit.xml 文件中声明了必要的环境变量,例如: <?xml version="1.0" encoding="UTF-8"?> <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd" colors="true" bootstrap="vendor/autoload.php" cacheResultFile=".phpunit.cache/test-results" executionOrder="depends,defects" forceCoversAnnotation="true" beStrictAboutCoversAnnotation="true" beStrictAboutOutputDuringTests="true" beStrictAboutTodoAnnotatedTests="true" convertDeprecationsToExceptions="true" failOnRisky="true" failOnWarning="true" verbose="true" > <php> <ini name="display_errors" value="1" /> <ini name="error_reporting" value="1" /> <env name="APP_ENV" value="test" force="true" /> <env name="KERNEL_CLASS" value="App\Kernel" /> <env name="APP_DEBUG" value="false" /> <env name="DATABASE_URL" value="sqlite:///:memory:" force="true" /> <var name="DB_DBNAME" value="app" /> </php> <testsuites> <testsuite name="Test Suite"> <directory>tests</directory> </testsuite> </testsuites> <coverage cacheDirectory=".phpunit.cache/code-coverage" processUncoveredFiles="true"> <include> <directory suffix=".php">src</directory> </include> <exclude> <directory>src/Entity</directory> <directory>src/Repository</directory> <file>src/Kernel.php</file> </exclude> </coverage> <listeners> <listener class="Symfony\Bridge\Phpunit\SymfonyTestsListener" /> </listeners> <extensions> <extension class="Symfony\Component\Panther\ServerExtension" /> </extensions> </phpunit> 为了设置所有功能测试,我们在tests/Framework/FunctionalTestCase.php 上初始化数据库模式 <?php namespace App\Tests\Framework; use App\Tests\Framework\DatabaseUtil\InitDatabase; use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\KernelBrowser; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; class FunctionalTestCase extends WebTestCase { protected EntityManagerInterface|null $entityManager = null; private KernelBrowser|null $client = null; protected function setUp(): void { parent::setUp(); self::ensureKernelShutdown(); $this->client = static::createClient(); InitDatabase::updateSchema($this->client); $this->entityManager = $this->client->getContainer() ->get('doctrine') ->getManager(); } protected function getClientFromParent(): KernelBrowser { return $this->client; } } 以及测试/Framework/DatabaseUtil/InitDataBase.php: <?php namespace App\Tests\Framework\DatabaseUtil; use Doctrine\ORM\Tools\SchemaTool; class InitDatabase { public static function updateSchema(object $kernel): void { $entityManager = $kernel->getContainer()->get('doctrine.orm.entity_manager'); $metaData = $entityManager->getMetadataFactory()->getAllMetadata(); $schemaTool = new SchemaTool($entityManager); $schemaTool->updateSchema($metaData); } } 使用 我们在 ControllerTests 中使用这个FunctionalTestCase,例如: <?php namespace App\Tests\Controller\AnyController; use App\Tests\Framework\FunctionalTestCase; use App\Entity\User; use App\TestsDataFixture\UserFixture; use Doctrine\Common\Collections\Collection; use Doctrine\DBAL\Exception\TableNotFoundException; use Doctrine\Persistence\ObjectManager; class AnyControllerTest extends FunctionalTestCase { private User $user; private User $entityUser; private KernelBrowser $client; public function setUp(): void { parent::setUp(); $userFixture = new UserFixture(); $this->user = $userFixture->load($this->entityManager); $this->entityUser = $this->entityManager->getRepository(User::class)->findAll()[0]; $this->client = $this->getClientFromParent(); } public function tearDown(): void { parent::tearDown(); $this->delete([$this->entityUser], $this->entityManager); } public function testLoginSuccessful(): void { $payload = [ 'username' => $this->user->getEmail(), 'password' => $this->user->getPassword() ]; $this->client->loginUser($this->user); $this->client->request( 'POST', '/auth/login', [], [], [ 'Content-Type' => 'application/json' ], json_encode($payload) ); $response = $this->client->getResponse()->getContent(); $data = json_decode($response, true); $this->assertResponseIsSuccessful(); $this->assertIsString($data['token']); } private function deleteFromDatabase(array|Collection $entities, ObjectManager $manager): void { $connection = $manager->getConnection(); $databasePlatform = $connection->getDatabasePlatform(); if ($databasePlatform->supportsForeignKeyConstraints()) { $connection->query('SET FOREIGN_KEY_CHECKS=0'); } foreach($entities as $entity) { try { $query = $databasePlatform->getTruncateTableSQL( $manager->getClassMetadata(get_class($entity))->getTableName() ); $connection->executeUpdate($query); } catch(TableNotFoundException $exception) { // do nothing } } if ($databasePlatform->supportsForeignKeyConstraints()) { $connection->query('SET FOREIGN_KEY_CHECKS=1'); } } } UserFixture 是一个普通的 DataFixture,具有用于生成 FakeUser 的加载方法,如下例所示:https://symfony.com/bundles/DoctrineFixturesBundle/current/index.html 您可以将私有删除方法放入特征中,以便在多个控制器中使用。 在此示例中,我们使用内存中的 sqlite 数据库,但您也可以将 phpunit 中的 DATABASE_URL 更改为 MariaDB DSN。
编写功能测试时将会话中的用户附加到当前EntityManager
我正在为与用户实体有关系的操作实体编写功能测试: 我正在为与 Action 实体有关系的 User 实体编写功能测试: <?php namespace Acme\AppBundle\Entity; /** * Class Action * * @ORM\Table() * @ORM\Entity(repositoryClass="Acme\AppBundle\Repository\ActionRepository") */ class Action { /** * @var int * * @ORM\Column(type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ private $id; /** * @var \Acme\AppBundle\Entity\User * * @ORM\ManyToOne(targetEntity="\Acme\AppBundle\Entity\User", inversedBy="actions") * @ORM\JoinColumn(name="user_id", referencedColumnName="id") */ private $createdBy; } 用户: namespace Acme\AppBundle\Entity; /** * @ORM\Entity * @ORM\Table(name="`user`") */ class User extends BaseUser { /** * @ORM\Id * @ORM\Column(type="integer") * @ORM\GeneratedValue(strategy="AUTO") */ protected $id; /** * @var ArrayCollection * * @ORM\OneToMany(targetEntity="Action", mappedBy="createdBy") */ private $actions; } 用户使用以下代码片段在控制器中设置: <?php namespace Acme\ApiBundle\Controller; /** * * @Route("/actions") */ class ActionController extends FOSRestController { public function postAction(Request $request) { $action = new Action(); $action->setCreatedBy($this->getUser()); return $this->processForm($action, $request->request->all(), Request::METHOD_POST); } } 例如,当使用 REST 客户端调用操作时,一切正常,Action 和 User 之间的关系正确保留。 现在,当使用功能测试来测试操作时,由于以下错误,该关系不起作用: 通过关系“Acme\AppBundle\Entity\Action#createdBy”找到了一个新实体,该实体未配置为实体的级联持久操作:测试。要解决此问题:对此未知实体显式调用 EntityManager#persist() 或配置级联在映射中保留此关联,例如 @ManyToOne(..,cascade={"persist"})。 对于我的功能测试,我需要注入 JWT 和会话令牌,因为我的路由由 JWT 保护,并且我需要在会话中拥有用户。 这是我注入的方法: <?php namespace Acme\ApiBundle\Tests; class ApiWebTestCase extends WebTestCase { /** * @var ReferenceRepository */ protected $fixturesRepo; /** * @var Client */ protected $authClient; /** * @var array */ private $fixtures = []; protected function setUp() { $fixtures = array_merge([ 'Acme\AppBundle\DataFixtures\ORM\LoadUserData' ], $this->fixtures); $this->fixturesRepo = $this->loadFixtures($fixtures)->getReferenceRepository(); $this->authClient = $this->createAuthenticatedClient(); } /** * Create a client with a default Authorization header. * * @return \Symfony\Bundle\FrameworkBundle\Client */ protected function createAuthenticatedClient() { /** @var User $user */ $user = $this->fixturesRepo->getReference('user-1'); $jwtManager = $this->getContainer()->get('lexik_jwt_authentication.jwt_manager'); $token = $jwtManager->create($user); $this->loginAs($user, 'api'); $client = static::makeClient([], [ 'AUTHENTICATION' => 'Bearer ' . $token, 'CONTENT_TYPE' => 'application/json' ]); $client->disableReboot(); return $client; } } 现在,问题是注入的 UsernamePasswordToken 包含一个与当前 User 分离的 EntityManager 实例,从而导致上面的 Doctrine 错误。 我可以将 $user 方法中的 postAction 对象合并到 EntityManager 中,但我不想这样做,因为这意味着我修改我的工作代码以使测试通过。 我还尝试将测试中的 $user 对象直接合并到 EntityManager 中,如下所示: $em = $client->getContainer()->get('doctrine')->getManager(); $em->merge($user); 但它也不起作用。 所以现在,我陷入了困境,我真的不知道该怎么办,除了我需要将会话中的用户附加回当前EntityManager。 您收到的错误消息表明测试客户端容器中包含的 EntityManager 不了解您的 User 实体。这让我相信您在 createAuthenticatedClient 方法中检索 User 的方式是使用不同的 EntityManager。 我建议您尝试使用测试内核的 EntityManager 来检索 User 实体。例如,您可以从测试客户端的容器中获取它。 感谢您的推文,我来完成给定的答案并(尝试)提出解决方案, 问题是您的用户不受 EntityManager 管理,更简单地说,因为它不是在数据库中注册的真实现有用户。 要解决此问题,您需要有一个真正的(托管)用户,该规则可以用于您的操作试图创建的关联。 因此,您可以在每次执行功能测试用例时创建此用户(并在完成后将其删除),或者仅在新环境中首次执行测试用例时创建一次。 这样的事情应该可以解决问题: /** @var EntityManager */ private $em; /** */ public function setUp() { $client = static::createClient(); $this->em = $client->getKernel() ->getContainer() ->get('doctrine'); $this->authClient = $this->createAuthenticatedClient(); } /** */ protected function createAuthenticatedClient() { /** @var User $user */ $user = $this->em ->getRepository('Acme\AppBundle\Entity\User') ->findOneBy([], ['id' => DESC]; // Fetch the last created // ... return $client; } 这对你的灯具来说是一个遗憾(它们太性感了),但我看不到任何方法可以将你的灯具作为真正的入口附加起来,因为你无法与测试的控制器进行更多交互。 另一种方法是向您的登录端点创建请求,但这会更难看。
我正在运行一个名为“创建管理”的测试。测试会先创建admin,然后检查admin是否创建成功。 在脚本中,我有一部分代码我想等待 3 秒 b...
我正在尝试将项目的php版本从php 7.4升级到php 8.1, 现在我将composer.json中的php版本更改为php 8.1,如下所示: “要求”: { “php”:“^8....
嗨,我正在测试这个应用程序。应用程序本身将填充该值并单击按钮以在表中提供数据。然而,实际上加载数据本身需要 40 秒以上,所以
空手道匹配两个 json 文件(预期 json 和 API 响应),无论数组元素的顺序如何
预期回应: {“数据”:{ {“作业”:[{“locationId”:“1186755”,“locationName”:“X.11.11”},{“locationId”:“1186756”,&
针对 Java 应用程序的机器人框架编写的测试用例的代码覆盖率报告
我有一个场景,我试图获取我们使用机器人框架编写的功能测试用例的覆盖率报告。 应用程序后端是用java编写的,UI代码是用Vue.js编写的
我有一个 250 行以内的 javascript 应用程序,想为其添加测试。每当我进行微小的更改时,我都必须手动运行至少 10 个案例的测试,我希望将其自动化。 我本来可以去...
是否有内置方法可以在测试控制器时完全跳过授权? 控制器示例: 公共函数changePassword(请求$ request,LdapInterface $ ldap) { $这个->
如何在 PHPUnit WebTestCase (Symfony 5) 中访问 Session
我正在尝试在我的 PHPUnit WebTestCase 中测试需要会话的方法,但没有成功。 PHP 8.0、Symfony 5.4 这是我的代码: 当用户登录时,我在会话中保存自定义信息: 公共职能...
我的应用程序要求应用程序以 https 运行,因为浏览器通过 JavaScript 库将支付数据发送到支付网关。 如果应用程序在 http 中运行,则付款会引发此错误
我正在使用实体框架作为我的存储库构建一个系统,虽然我同意我不应该测试实体框架,但我希望能够验证我围绕实体框架的逻辑...
我在我的应用程序中安装了 RailsAdmin 引擎(根据 wiki 的说明)使用 mount RailsAdmin::Engine => '/backend', :as => 'rails_admin' 我不得不从 ...
使用 Selenium 测试 JS 函数的问题,在 Django 上设置:“selenium.common.exceptions.TimeoutException: Message”
我只想测试 getRates() 函数。但是我遇到了无法修复的错误: selenium.common.exceptions.TimeoutException 或者我收到未定义 getRates 的错误。 函数 getRates(