ujian


Setiap kali anda menulis baris tambahan kod, anda menambah potensi pepijat baharu. Untuk membina atur cara yang lebih baik dan lebih dipercayai, anda perlu menggunakan ujian fungsian dan unit pada kod anda.

Rangka kerja ujian PHPUnit

Symfony menyepadukan perpustakaan kelas bebas - bernama PHPUnit - untuk membawakan anda rangka kerja ujian yang kaya. Bab ini tidak merangkumi PHPUnit itu sendiri, tetapi ia mempunyai dokumentasi yang sangat baik sendiri.

Adalah disyorkan untuk menggunakan versi stabil terkini PHPUnit, pasang PHAR.

Setiap ujian – sama ada ujian unit atau ujian berfungsi – ialah kelas PHP, disimpan dalam Tests/ subdirektori Himpunan anda. Jika anda mengikuti prinsip ini, maka apabila menjalankan semua ujian peringkat program, jalankan sahaja arahan berikut:

1
$  phpunit

PHPunit dikonfigurasikan melalui fail phpunit.xml.dist dalam direktori akar Symfony. phpunit.xml.dist 文件进行配置。

代码覆盖(code coverage)可以通过 —coverage-* 选项来生成。要查看帮助信息,可使用 —help 来显示更多内容。

单元测试 

单元测试是针对单一PHP类的测试,这个类也被称为“单元(unit)”。如果你需要测试你的应用程序层级的整体行为,参考[功能测试] (#catalog2)(Functional Tests)。

编写Symfony单元测试和编写标准的PHPUnit单元测试并无不同。假设,你有一个极其简单的类,类名是 Calculator ,位于app bundle的 Util/ 目录下:

// src/AppBundle/Util/Calculator.phpnamespace AppBundle\Util; class Calculator{
    public function add($a, $b)
    {
        return $a + $b;
    }}

为了测试它,创建一个 CalculatorTest 文件到你的bundle的 tests/AppBundle/Util  目录下:

// tests/AppBundle/Util/CalculatorTest.phpnamespace Tests\AppBundle\Util; use AppBundle\Util\Calculator; class CalculatorTest extends \PHPUnit_Framework_TestCase{
    public function testAdd()
    {
        $calc = new Calculator();
        $result = $calc->add(30, 12);         // assert that your calculator added the numbers correctly!
        $this->assertEquals(42, $result);
    }}


根据约定, Tests/AppBundle 目录应该复制你的bundle下的单元测试文件所在的目录。因此,如果你要测试的类位于 src/AppBundle/Util 目录下,那么就把测试代码放在 tests/AppBundle/Util/

Liputan kod boleh dijana melalui pilihan —liputan-*. Untuk melihat maklumat bantuan, gunakan —help untuk memaparkan lebih banyak kandungan.
🎜🎜

Ujian unit

🎜Ujian unit ialah ujian untuk kelas PHP tunggal juga Ia dipanggil "unit". Jika anda perlu menguji kelakuan keseluruhan hierarki aplikasi anda, lihat Ujian Fungsian (#catalog2). 🎜🎜Menulis ujian unit Symfony tidak berbeza dengan menulis ujian unit PHPUnit standard. Katakan, anda mempunyai kelas yang sangat mudah bernama Kalkulator, terletak dalam direktori Util/ app bundle: 🎜
# run all tests of the application# 运行程序中的所有测试$  phpunit
 # run all tests in the Util directory# 运行指定目录下的所有测试$  phpunit tests/AppBundle/Util
 # run tests for the Calculator class# 仅运行Calculator类的测试$  phpunit tests/AppBundle/Util/CalculatorTest.php
 # run all tests for the entire Bundle# 运行整个bundle的测试$  phpunit tests/AppBundle/
🎜Untuk mengujinya, buat CalculatorTest< /code> ke direktori tests/AppBundle/Util bundle anda:
🎜
// tests/AppBundle/Controller/PostControllerTest.phpnamespace Tests\AppBundle\Controller; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; class PostControllerTest extends WebTestCase{
    public function testShowPost()
    {
        $client = static::createClient();         $crawler = $client->request('GET', '/post/hello-world');         $this->assertGreaterThan(
            0,
            $crawler->filter('html:contains("Hello World")')->count()
        );
    }}
🎜
🎜
🎜 Mengikut konvensyen, direktori Tests/AppBundle hendaklah disalin ke direktori tempat fail ujian unit di bawah berkas anda berada. Oleh itu, jika kelas yang anda ingin uji terletak dalam direktori src/AppBundle/Util, kemudian letakkan kod ujian dalam direktori tests/AppBundle/Util/. 🎜🎜


Sama seperti aplikasi sebenar anda – autoloading didayakan secara automatik melalui fail bootstrap.php.cache (bahagian konfigurasi ini ada dalam app/phpunit.xml secara lalai. fail dist) bootstrap.php.cache 文件来完成(这部分的配置默认是在app/phpunit.xml.dist文件中)

针对指定文件或目录的测试也很简单:

<?xml version="1.0" charset="utf-8" ?><phpunit>
    <php>
        <server name="KERNEL_DIR" value="/path/to/your/app/" />
    </php>
    <!-- ... --></phpunit>

功能测试 

功能测试(Functional tests)检查程序不同层面的整合情况(从路由到视图)。这些层面本身并不因PHPUnit的介入而发生改变,只不过它们有着独特的工作流:

  • 制造一个请求(request);

  • 测试响应(response);

  • 点击一个链接,或提交一个表单;

  • 测试响应;

  • 清除然后重复。

你的第一个功能测试 

功能测试是存放在 Test/AppBundle/Controller 目录下的普通PHP文件。如果要测试由你的 PostController 处理的页面,先创建一个新的PostControllerTest.php文件,并继承一个特殊的 WebTestCase 类。

作为例程,这个测试看起来可能像下面代码:

1


为了运行上面的功能测试,  WebTestCase 类启动了程序内核。在多数情况下,这是自动完成的。但如果kernel位于非标准目录,你需要调整 phpunit.xml.dist 文件,重新设置 KERNEL_DIR 环境变量为你的kernel目录:


$crawler = $client->request('GET', '/post/hello-world');

createClient()

Ujian untuk fail atau direktori yang ditentukan juga sangat mudah:
$link = $crawler
    ->filter('a:contains("Greet")') // 选择所有含有"Greet"文本之链接
    ->eq(1) // 结果列表中的第二个
    ->link() // 点击它; $crawler = $client->click($link);
Ujian fungsional Fungsi Semakan ujian fungsional penyepaduan peringkat program yang berbeza (dari penghalaan kepada paparan). Tahap ini sendiri tidak berubah disebabkan oleh campur tangan PHPUnit, tetapi mereka mempunyai aliran kerja yang unik: Uji respons (respons ); li>
  • Kosongkan dan ulangi.

    Ujian fungsi pertama anda

    • Buat permintaan
    Klik pautan, atau serahkan borang
  • Uji respons
    Ujian fungsian Ia adalah fail PHP biasa yang disimpan dalam direktori Test/AppBundle/Controller. Jika anda ingin menguji halaman yang dikendalikan oleh PostController anda, mula-mula buat fail PostControllerTest.php baharu dan warisi kelas WebTestCase khas. 🎜🎜Sebagai rutin, ujian ini mungkin kelihatan seperti kod berikut: 🎜
    $form = $crawler->selectButton('submit')->form(); // 设置一些值$form['name'] = 'Lucas';$form['form_name[subject]'] = 'Hey there!'; // 提交表单$crawler = $client->submit($form);
    🎜🎜🎜
    🎜Untuk menjalankan ujian berfungsi di atas, WebTestCase kelas dimulakan Kernel program. Dalam kebanyakan kes, ini dilakukan secara automatik. Tetapi jika kernel terletak dalam direktori bukan standard, anda perlu melaraskan fail phpunit.xml.dist dan menetapkan semula pembolehubah persekitaran KERNEL_DIR ke direktori kernel anda: 🎜 🎜🎜🎜🎜
    // Assert that the response matches a given CSS selector.// 断言响应内容匹配到一个指定的CSS拾取器$this->assertGreaterThan(0, $crawler->filter('h1')->count());
    🎜 Kaedah createClient() mengembalikan klien, yang boleh digunakan untuk mensimulasikan penyemak imbas supaya anda boleh merangkak halaman tapak web: 🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜 🎜
    $this->assertContains(
        'Hello World',
        $client->getResponse()->getContent());
    🎜🎜🎜🎜🎜

    kaedah permintaan() (rujuk Lagi kaedah permintaan request()方法 (参考 更多请求方法)返回了一个 Crawler 对象,用于从响应内容中选择元素(select elements),完成点击链接或提交表单这样的动作。

    响应信息必须是XML或HTML文档格式,抓取器(Crawler)才会工作。若需要不带文档格式的纯响应内容(raw content),请使用 $client->getResponse()->getContent()

    需要点击链接时,先用抓取器选择它,可使用XPath表达式或CSS拾取器来完成选 择,然后再使用client行为来点击它:

    use Symfony\Component\HttpFoundation\Response; // ... // Assert that there is at least one h2 tag// with the class "subtitle"// 断言至少有一个h2标签,其class是subtitle$this->assertGreaterThan(
        0,
        $crawler->filter('h2.subtitle')->count()); // Assert that there are exactly 4 h2 tags on the page// 断言页面有4个h2标签$this->assertCount(4, $crawler->filter('h2')); // Assert that the "Content-Type" header is "application/json"// 断言Content-Type头是application/json$this->assertTrue(
        $client->getResponse()->headers->contains(
            'Content-Type',
            'application/json'
        )); // Assert that the response content contains a string// 断言响应信息中包含一个字符串$this->assertContains('foo', $client->getResponse()->getContent());// ...or matches a regex$this->assertRegExp('/foo(bar)?/', $client->getResponse()->getContent()); // Assert that the response status code is 2xx// 断言响应状态码是2xx$this->assertTrue($client->getResponse()->isSuccessful());// Assert that the response status code is 404// 断言响应状态码是404$this->assertTrue($client->getResponse()->isNotFound());// Assert a specific 200 status code// 断言响应状态码是特殊的200$this->assertEquals(
        200, // or Symfony\Component\HttpFoundation\Response::HTTP_OK
        $client->getResponse()->getStatusCode()); // Assert that the response is a redirect to /demo/contact// 断言响应是一个指向/demo/contact的跳转$this->assertTrue(
        $client->getResponse()->isRedirect('/demo/contact'));// ...or simply check that the response is a redirect to any URL// 或者仅言响应是一个跳转,不管指向的URL是什么$this->assertTrue($client->getResponse()->isRedirect());

    提交表单时非常相似:选取一个表单按钮,可选地覆写某些表单项的值,然后提交对应的表单:

    1

    表单也可以处理上传,它还包含了用于填写不同类型的表单字段的方法(例如 select()tick()) mengembalikan Crawler objek, gunakan Untuk memilih elemen daripada kandungan respons, menyelesaikan tindakan seperti mengklik pautan atau menyerahkan borang.

    Maklumat respons mestilah dalam format dokumen XML atau HTML dan perangkak (Crawler ) mesti akan berfungsi. Jika anda memerlukan kandungan mentah tanpa format dokumen, sila gunakan $client->getResponse()->getContent() .

    Apabila anda perlu mengklik pada pautan, mula-mula pilih dengan grabber Anda boleh menggunakan ekspresi XPath atau pemilih CSS untuk melengkapkan pemilihan, dan kemudian gunakan gelagat klien untuk mengkliknya. :

    $crawler = $client->request('GET', '/post/hello-world');

    Menyerahkan borang adalah sangat serupa: pilih butang borang, secara pilihan menggantikan nilai beberapa item borang, dan kemudian serahkan borang yang sepadan:
    #🎜 🎜#
    request(
        $method,
        $uri,
        array $parameters = array(),
        array $files = array(),
        array $server = array(),
        $content = null,
        $changeHistory = true)

    Borang juga boleh mengendalikan muat naik, dan ia juga mengandungi kaedah untuk mengisi pelbagai jenis borang medan (seperti < code>select() dan tick() ). Untuk butiran, sila rujuk bahagian berikut

    Borang
    .

    Kini anda boleh bergerak melalui program anda dengan mudah, menggunakan penegasan untuk menguji sama ada halaman berkelakuan seperti yang anda jangkakan. Gunakan Crawler untuk membuat penegasan bertindak pada DOM.

    $client->request(
        'GET',
        '/post/hello-world',
        array(),
        array(),
        array(
            'CONTENT_TYPE'          => 'application/json',
            'HTTP_REFERER'          => '/foo/bar',
            'HTTP_X-Requested-With' => 'XMLHttpRequest',
        ));

    Atau uji kandungan respons secara langsung, jika anda hanya ingin menegaskan sama ada kandungan tersebut mengandungi teks tertentu, atau hanya tahu bahawa kandungan respons bukan dalam format XML/HTML:

    $link = $crawler->selectLink('Go elsewhere...')->link();$crawler = $client->click($link); $form = $crawler->selectButton('validate')->form();$crawler = $client->submit($form, array('name' => 'Fabien'));
    # 🎜🎜#

    Pernyataan berguna

    Untuk membantu anda menguasai ujian secepat mungkin, contoh-contoh berikut menyenaraikan yang paling biasa pernyataan yang digunakan Dan pernyataan ujian yang paling berguna:

    // Directly submit a form (but using the Crawler is easier!)// 直接提交表单(但是使用Crawler更容易些)$client->request('POST', '/submit', array('name' => 'Fabien')); // Submit a raw JSON string in the request body// 在请求过程中提交一个JSON原生串$client->request(
        'POST',
        '/submit',
        array(),
        array(),
        array('CONTENT_TYPE' => 'application/json'),
        '{"name":"Fabien"}'); // Form submission with a file upload// 文件上传表单的提交use Symfony\Component\HttpFoundation\File\UploadedFile; $photo = new UploadedFile(
        '/path/to/photo.jpg',
        'photo.jpg',
        'image/jpeg',
        123);$client->request(
        'POST',
        '/submit',
        array('name' => 'Fabien'),
        array('photo' => $photo)); // Perform a DELETE request and pass HTTP headers// 执行一个DELETE请求并传递HTTP头$client->request(
        'DELETE',
        '/post/12',
        array(),
        array(),
        array('PHP_AUTH_USER' => 'username', 'PHP_AUTH_PW' => 'pa$$word'));

    Pemalar kod status HTTP yang diperkenalkan daripada Symfony 2.4

    #🎜🎜 Test Client 🎜🎜#¶
    1
    #🎜#
    Pelanggan ujian mensimulasikan klien HTTP, sama seperti penyemak imbas, yang boleh menjana permintaan untuk program Symfony anda.
    #🎜🎜##🎜🎜##🎜🎜#
    $client->insulate();
    #🎜🎜##🎜##🎜🎜🎜🎜##🎜 #🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜#Kaedah

    request() menerima parameter permintaan HTTP dan parameter URL serta mengembalikan tika Crawler. request() 方法接受一个HTTP请求方式的参数和一个URL参数,返回一个Crawler实例。

    对于功能测试来说,写死request链接是最佳实践。如果在测试中生成URL时使用Symfony路由,它将无法侦测到针对此URL页面的任何改变,这可能导致用户体验受到冲击。

    以下是更多关于request()方法的例子:

    request()方法的完整用例:

    $client->back();$client->forward();$client->reload(); // Clears all cookies and the history// 清除所有cookie和历史记录$client->restart();

    其中的 server 数组存放了你可能期待使用的PHP超全局变量$_SERVER的原生键值。例如,设置 Content-TypeRefererX-Requested-With (HTTP头)时,你需要传入以下参数(注意用于非标准头的 HTTP_ 前缀):

    $history = $client->getHistory();$cookieJar = $client->getCookieJar();

    使用抓取器来找到响应内容中的DOM元素。这些元素可以被用在点击链接或提交表单等场合:

    // the HttpKernel request instance// HttpKernel的请求实例$request = $client->getRequest(); // the BrowserKit request instance// 浏览器组件的请求实例$request = $client->getInternalRequest(); // the HttpKernel response instance// HttpKernel的响应实例$response = $client->getResponse(); // the BrowserKit response instance// 浏览器组件的响应实例$response = $client->getInternalResponse(); $crawler = $client->getCrawler();

    此处的 click() 方法和 submit() 方法,都会返回一个 crawler 抓取器对象。这些方法是浏览你的程序页面的最佳方式,因为它们帮你做了很多事,像是从表单中侦测HTTP请求方式,或者给你提供一个很好的API用于文件上传。

    在后面的 Crawler 小节中你将学习到更多关于链接Link和表单Form对象的知识。

    request

    Untuk ujian berfungsi, pengekodan keras pautan permintaan ialah amalan terbaik. Jika anda menggunakan penghalaan Symfony semasa menjana URL dalam ujian anda, ia tidak akan dapat mengesan sebarang perubahan pada halaman URL, yang mungkin mengakibatkan pengalaman pengguna terjejas.


    Berikut adalah lebih lanjut mengenai permintaan( ) contoh kaedah:

    Kes penggunaan lengkap kaedah request():
    $container = $client->getContainer();$kernel = $client->getKernel();
    Tatasusunan pelayan menyimpan perkara yang anda jangkakan Nilai kunci asli pembolehubah superglobal PHP $_SERVER digunakan. Contohnya, apabila menetapkan Content-Type, Referer, X-Requested-With (pengepala HTTP), anda perlu memasukkan parameter berikut (perhatikan penggunaan awalan HTTP_ untuk pengepala bukan standard):
    1
    $container = $client->getContainer();
    Crawler Dalam bahagian ini anda akan mengetahui lebih lanjut tentang objek Pautan dan Borang.
    Gunakan pengikis untuk mencari elemen DOM dalam kandungan respons. Elemen ini boleh digunakan apabila mengklik pada pautan atau menyerahkan borang:
    Kaedah click() dan submit() kaedah akan mengembalikan objek perangkak crawler. Kaedah ini ialah cara terbaik untuk menyemak imbas halaman aplikasi anda kerana ia melakukan banyak perkara untuk anda, seperti mengesan corak permintaan HTTP daripada borang, atau memberikan anda API yang bagus untuk muat naik fail.
    #🎜🎜# Kaedah permintaan juga boleh digunakan untuk mensimulasikan penyerahan borang secara langsung atau untuk melaksanakan permintaan yang lebih kompleks. Beberapa contoh berguna: #🎜🎜#
    // enable the profiler for the very next request// 为接下来的请求开启profiler$client->enableProfiler(); $crawler = $client->request('GET', '/profiler'); // get the profile 得到分析器$profile = $client->getProfile();
    #🎜🎜#Sebagai peringatan terakhir, anda boleh memaksa setiap permintaan untuk dilaksanakan dalam proses PHP mereka sendiri untuk mengelakkan kesan sampingan apabila terdapat berbilang pelanggan dalam skrip yang sama. #🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜#
    1
    #🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜 🎜🎜#
    $crawler = $client->followRedirect();
    #🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜#. Jika anda menggunakan klien untuk menguji program anda, anda mungkin mahu menggunakan beberapa objek di dalam klien:
    1

    Anda juga boleh mendapatkan objek yang berkaitan dengan permintaan terkini:
    $client->followRedirects();

    Jika permintaan anda tidak berasingan Semasa menjalankan, anda juga boleh menggunakan Bekas (bekas) dan Kernel (kernel):

    1

    Gunakan bekas

    Sangat disyorkan bahawa ujian berfungsi hanya menguji respons. Tetapi dalam kes yang jarang berlaku, anda mungkin mahu menggunakan objek dalaman untuk menulis penegasan. Pada masa ini, anda boleh memanggil Bekas Suntikan Ketergantungan (bekas suntikan ketergantungan, iaitu bekas perkhidmatan):



    $client->followRedirects(false);

    Container (容器)和 Kernel (内核):

    $newCrawler = $crawler->filter('input[type=submit]')
        ->last()
        ->parents()
        ->first();

    使用容器 

    强烈推荐功能测试只测试响应。但在特定的罕见情况下,你可能要使用内部对象来书写断言。这时,你可以调用Dependency Injection Container(依赖注入容器,即服务容器):

    $crawler
        ->filter('h1')
        ->reduce(function ($node, $i) {
            if (!$node->getAttribute('class')) {
                return false;
            }
        })
        ->first();
    // 返回第一个节点的属性值$crawler->attr('class'); // 返回第一个节点的节点文本$crawler->text(); // Extracts an array of attributes for all nodes// (_text returns the node value)// returns an array for each element in crawler,// each with the value and href// 提取一个由所有节点的属性组成的数组// (_text返回节点值)// 返回一个由抓取器中的每一个元素所组成的数组// 每个元素有value和href$info = $crawler->extract(array('_text', 'href')); // Executes a lambda for each node and return an array of results// 对每个节点执行一次lambda函数(即匿名函数),最后返回结果数组$data = $crawler->each(function ($node, $i) {
        return $node->attr('href');});

    注意,如果你是把client隔离运行或者使用一个HTTP layer的话,上述功能无效。程序中的可用服务列表,你可通过 debug:container 命令行工具来查看。

    在Symfony2.6之前这个命令是 container:debug

    如果你需要检查的信息在分析器(profiler)中可用,那么应使用profiler来替代container。

    使用分析数据 

    每一次请求,你都可以借助Symfony分析器(profiler)来收集关于该请求在内部被处理的有关信息。例如,分析器常被用于验证指定页面在加载过程中的数据库查询次数是否小于给定值。

    为了得到最近一次请求的Profiler,按下例操作:

    1

    在测试中使用分析器的某些细节,请参阅 如何在功能测试中使用分析器 一文。

    重定向 

    当一个请求返回的是重定向响应时,client并不自动跟进。你可以检测该响应信息,然后通过 followRedirect()

    $crawler->selectLink('Click here');
    $link = $crawler->selectLink('Click here')->link(); $client->click($link);
    1
    🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜 klien secara berasingan Atau jika anda menggunakan lapisan HTTP, fungsi di atas adalah tidak sah. Anda boleh melihat senarai perkhidmatan yang tersedia dalam program melalui alat baris arahan debug:container. 🎜🎜🎜Sebelum Symfony2.6, arahan ini ialah container:debug. 🎜🎜

    Jika anda memerlukan pelanggan mengikuti semua ubah hala secara automatik, anda boleh memaksanya untuk melaksanakan, gunakan kaedah followRedirects(): followRedirects() 方法:

    $form = $buttonCrawlerNode->form(array(
        'name'              => 'Fabien',
        'my_form[subject]'  => 'Symfony rocks!',));
    1

    false 传给 followRedirects()

    Crawler

    Ada crawler setiap kali anda membuat permintaan melalui instance pelanggan (Crawler) dikembalikan. Pengikis membolehkan anda melintasi dokumen HTML, mengambil nod DOM dan mencari pautan dan borang.

    Traversing

    Sama seperti JQuery, perangkak mempunyai pelbagai kaedah untuk melintasi DOM dokumen HTML/XML. Sebagai contoh, kaedah berikut mencari semua elemen input[type=submit], memilih yang terakhir pada halaman dan kemudian memilih elemen induk bersebelahannya: input[type=submit] 元素,并选择页面中的最后一个,然后选择它的临近父元素:

    $client->submit($form);

    还有很多其他方法可以利用:

    • filter('h1.title')
    • 匹配CSS拾取器的所有节点。
    • filterXpath('h1')
    • 匹配XPath expression(表达式)的所有节点。
    • eq(1)
    • 指定索引的节点。
    • first()
    • 第一个节点。
    • last()
    • 最后一个节点。
    • siblings()
    • Siblings。
    • nextAll()
    • 后续所有siblings。
    • previousAll()
    • 之前所有siblings。
    • parents()
    • 返回所有父节点。
    • children()
    • 返回所有子节点。
    • reduce($lambda)
    • 匿名函数$lambda不返回false时的所有节点。

    由于上述每个方法都返回一个 Crawler 抓取器对象,你可以通过对各方法的链式调用来减少节点拾取过程的代码:

    $client->submit($form, array(
        'name'              => 'Fabien',
        'my_form[subject]'  => 'Symfony rocks!',));

    可以使用 count() 函数来得到存储在一个Crawler中的节点数量: count($crawler)

    提取信息 

    抓取器可以从节点中提到信息:

    // 改变某个字段的值/Change the value of a field$form['name'] = 'Fabien';$form['my_form[subject]'] = 'Symfony rocks!';

    链接 

    为了选择链接,你可以使用上述遍历方法,或者使用更方便的 selectLink()

    // 选取一个option单选或radio单选$form['country']->select('France'); // 选取一个checkbox$form['like_symfony']->tick(); // 上传一个文件$form['photo']->upload('/path/to/lucas.jpg');

    Juga Banyak kaedah lain boleh digunakan:
    • filter('h1.title')
    • < li> Memadankan semua nod pemilih CSS.
    • filterXpath('h1')
    • Semua nod yang sepadan dengan ungkapan (ungkapan) XPath.
    • eq(1)
    • Nod yang menentukan indeks.
    • first()
    • Nod pertama.
    • last()
    • Nod terakhir.
    • adik-beradik()
    • Adik beradik.
    • nextAll()
    • Semua adik-beradik seterusnya.
    • previousAll()
    • Semua adik-beradik terdahulu.
    • ibu bapa()
    • Mengembalikan semua nod induk.
    • kanak-kanak()
    • Mengembalikan semua nod anak.
    • reduce($lambda)
    • Semua nod apabila fungsi tanpa nama $lambda tidak mengembalikan palsu.
    Memandangkan setiap kaedah di atas mengembalikan objek perebut Crawler, anda boleh mengurangkan kod proses pemilihan nod dengan merantai panggilan ke setiap kaedah :#. 🎜🎜#
    // Get the form. 取得表单$form = $crawler->filter('button')->form(); // Get the raw values. 取得原始数值$values = $form->getPhpValues(); // Add fields to the raw values. 给原始数组添加新字段$values['task']['tag'][0]['name'] = 'foo';$values['task']['tag'][1]['name'] = 'bar'; // Submit the form with the existing and new values.// 提交表单,包括既有值,以及新值$crawler = $this->client->request($form->getMethod(), $form->getUri(), $values,
        $form->getPhpFiles()); // The 2 tags have been added to the collection.// 2个新标签被添加到collection中$this->assertEquals(2, $crawler->filter('ul.tags > li')->count());
    Anda boleh menggunakan fungsi count() untuk mendapatkan nombor yang disimpan dalam Crawler Bilangan nod: count($crawler)Perangkak boleh menyebut maklumat daripada nod:
    // Get the values of the form. 取得表单数据$values = $form->getPhpValues(); // Remove the first tag. 移除第一个标签unset($values['task']['tags'][0]); // Submit the data. 提交数据$crawler = $client->request($form->getMethod(), $form->getUri(),
        $values, $form->getPhpFiles()); // The tag has been removed. 标签已被移除$this->assertEquals(0, $crawler->filter('ul.tags > li')->count());
    Pautan
    Ekstrak maklumat

    #🎜🎜##🎜🎜#Untuk memilih pautan, anda boleh menggunakan kaedah traversal di atas atau gunakan selectLink() Kaedah pintasan: #🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜#
    PHP:// app/config/config_test.php // ...$container->loadFromExtension('swiftmailer', array(
        'disable_delivery' => true,));
    #🎜🎜##🎜🎜##🎜🎜 #🎜🎜#
    XML:<!-- app/config/config_test.xml --><?xml version="1.0" encoding="UTF-8" ?><container xmlns="http://symfony.com/schema/dic/services"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns:swiftmailer="http://symfony.com/schema/dic/swiftmailer"    xsi:schemaLocation="http://symfony.com/schema/dic/services        http://symfony.com/schema/dic/services/services-1.0.xsd        http://symfony.com/schema/dic/swiftmailer        http://symfony.com/schema/dic/swiftmailer/swiftmailer-1.0.xsd">     <!-- ... -->
        <swiftmailer:config disable-delivery="true" /></container>
    #🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜#

    Dengan cara ini anda boleh memilih semua pautan yang mengandungi teks yang diberikan atau imej boleh klik yang atribut altnya mengandungi teks yang diberikan . Sama seperti kaedah penapisan lain, ia juga mengembalikan objek Crawler. alt 属性中包含了给定文本。和其他的过滤方法类似,它也是返回一个 Crawler 对象。

    一旦你选中了一个链接(link),你就可以使用一个特殊的链接对象( link  object),它是一个专门用来处理链接的方法(类似 getMethod()getUri() 这种,都属于帮助方法/helpful method)。要点击链接,使用Client的 click() 方法,并把链接对象传进去:

    YAML:# app/config/config_test.yml # ...swiftmailer:
        disable_delivery: true

    表单 

    表单可以通过它们的按钮被选择,而按钮可以用selectButton()方法来选择,正如选择链接一样:

    $client = static::createClient(array(
        'environment' => 'my_test_env',
        'debug'       => false,));
    $client = static::createClient(array(), array(
        'HTTP_HOST'       => 'en.example.com',
        'HTTP_USER_AGENT' => 'MySuperBrowser/1.0',));

    注意你选择的是表单的按钮而不是表单本身,因为表单可以有多个按钮。如果你使用遍历API,记住必须要找到一个按钮。

    selectButton() 方法可以选中 button (按钮)标签,以及submit(提交)所在的标签(即 input 标签)。它使用按钮的几个部分来找到它们:

    • value 属性值(The value attribute value)

    • 图片按钮的 id 属性值或 alt 属性值(The id or alt attribute value for images)

    • button 标签的 id 属性值或 name 属性值(The id or name attribute value for button tags)

    当你有了一个含有button的crawler之后,调用 form() 方法即可得到拥有这个button节点的form实例。

    $client->request('GET', '/', array(), array(), array(
        'HTTP_HOST'       => 'en.example.com',
        'HTTP_USER_AGENT' => 'MySuperBrowser/1.0',));
    <!-- app/phpunit.xml.dist --><phpunit>
        <!-- ... -->
        <testsuites>
            <testsuite name="Project Test Suite">
                <directory>../src/*/*Bundle/Tests</directory>
                <directory>../src/*/Bundle/*Bundle/Tests</directory>
                <directory>../src/*Bundle/Tests</directory>
            </testsuite>
        </testsuites>
        <!-- ... --></phpunit>

    当调用 form()

    Setelah anda memilih pautan, anda boleh menggunakan objek pautan khas ( objek link), iaitu kaedah yang direka khusus untuk mengendalikan pautan ( Sama seperti getMethod( ) atau getUri(), semuanya adalah kaedah yang berguna). Untuk mengklik pautan, gunakan kaedah click() Pelanggan dan hantar objek pautan dalam:

    <!-- app/phpunit.xml.dist --><phpunit>
        <!-- ... -->
        <testsuites>
            <testsuite name="Project Test Suite">
                <!-- ... - - ->            <directory>../lib/tests</directory>        </testsuite>    </testsuites>    <!-- ... - - -></phpunit>

    Borang

    Borang boleh dipilih melalui butangnya dan butang boleh dipilih menggunakan kaedah selectButton(), sama seperti memilih pautan:
    <!-- app/phpunit.xml.dist --><phpunit>
        <!-- ... -->
        <filter>
            <whitelist>
                <!-- ... -->
                <directory>../lib</directory>
                <exclude>
                    <!-- ... -->
                    <directory>../lib/tests</directory>
                </exclude>
            </whitelist>
        </filter>
        <!-- ... - - -></phpunit>
    #🎜#rree ##🎜#rree
    # 🎜🎜#Perhatikan bahawa anda memilih butang borang dan bukannya borang itu sendiri, kerana borang boleh mempunyai berbilang butang. Jika anda menggunakan API traversal, ingat bahawa anda mesti mencari butang. #🎜🎜##🎜🎜##🎜🎜##🎜🎜#selectButton() kaedah boleh memilih button (butang) label dan label tempat serah (serahkan) terletak (iaitu teg input). Ia menggunakan beberapa bahagian butang untuk mencarinya: #🎜🎜#
    • #🎜🎜#nilai Nilai atribut nilai#🎜🎜#
    • < li>#🎜 🎜#Nilai atribut id atau alt untuk imej#🎜🎜#
    • #🎜🎜#Nilai atribut id atau nama untuk teg butang)#🎜🎜 #
    #🎜🎜 #Apabila anda mempunyai perangkak yang mengandungi butang, panggil kaedah form() untuk mendapatkan contoh borang dengan nod butang. #🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜#rrreee#🎜🎜##🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜#rrreee#🎜🎜##🎜##🎜🎜🎜🎜##🎜 #🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜#Apabila memanggil kaedah form(), anda juga boleh Hantar dalam tatasusunan yang mengandungi nilai medan borang untuk menggantikan yang lalai: #🎜🎜#rrreee#🎜🎜#Apabila anda ingin mensimulasikan kaedah penyerahan borang HTTP tertentu, masukkannya ke dalam parameter kedua: # 🎜🎜## 🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜#rrreee#🎜🎜##🎜#rr🎜 🎜🎜##🎜🎜##🎜🎜##🎜🎜##🎜🎜#

    Pelanggan bertanggungjawab menghantar contoh borang:

    rrreee
    rrreee

    Nilai medan boleh dihantar ke parameter kedua kaedah submit():

    rrreee

    Untuk situasi yang lebih kompleks, contoh borang boleh digunakan sebagai tatasusunan untuk menetapkan nilai yang sepadan dengan setiap medan:

    rrreee

    Terdapat juga API berguna untuk mengurus nilai medan berdasarkan jenisnya:

    rrreee

    Jika anda sengaja mahu memilih nilai pilihan/radio "tidak sah", rujuk Pilih Nilai Pilihan Tidak Sah .

    Anda boleh mendapatkan nilai medan borang yang akan diserahkan dengan memanggil kaedah getValues() objek Borang. Fail yang dimuat naik juga boleh diperoleh daripada tatasusunan terpisah yang dikembalikan melalui kaedah getFiles(). Kaedah getPhpValues() dan getPhpFiles() juga boleh mengembalikan medan yang diserahkan, tetapi dalam format PHP (ia memerlukan kunci dengan kurungan segi empat sama – seperti my_form[subject ] – ditukar kepada tatasusunan PHP). getValues() 方法即可。已上传的文件也可以从一个分离出来的数组得到,这个数组由 getFiles() 方法返回。 getPhpValues() 以及 getPhpFiles() 方法同样可以返回已经提交的字段,只不过是PHP格式的(它把带有方括号的键 – 比如 my_form[subject]  – 给转换成PHP数组)。

    添加或删除表单到Collection 

    如果你使用了 Collection of Forms(表单集合),你不能对既有表单添加一个 $form['task[tags][0][name]'] = 'foo 字段。这会导致一个 Unreachable field "…" 错误。因为 $form 只能被用于设置现有的字段。为了添加一个新字段,你不得不把值添加到一个原始数组中:

    rrreee

    这里的 task[tags][0][name] 就是由JavaScript创建的字段的名字。

    你可以移除一个既有字段,比如一个标签(tag):

    rrreee

    配置测试 

    功能测试所用到的Client创建了一个Kernel,用于在一个特殊的 test 测试环境中运行。由于Symfony在测试时加载的是 app/config/config_test.yml

    Tambah atau padamkan borang pada Koleksi

    , anda tidak boleh menambah medan $form['task[tags][0][name]'] = 'foo sedia ada. Ini mengakibatkan ralat Unreachable field "…". Kerana $form hanya boleh digunakan untuk menetapkan medan sedia ada. Untuk menambah medan baharu, anda perlu menambah nilai pada tatasusunan primitif: 🎜rrreee🎜 Di sini task[tags][0][name] ialah nama medan yang dicipta oleh JavaScript. 🎜🎜🎜Anda boleh mengalih keluar medan sedia ada, seperti teg: 🎜rrreee🎜Ujian konfigurasi ¶🎜🎜🎜🎜Ujian fungsian yang digunakan Pelanggan mencipta Kernel untuk dijalankan dalam persekitaran ujian test khas. Memandangkan Symfony memuatkan app/config/config_test.yml semasa ujian, anda boleh melaraskan sebarang tetapan "peringkat program" yang digunakan untuk ujian. 🎜🎜Sebagai contoh, Swift Mailer lalai ditetapkan untuk tidak menghantar e-mel dalam persekitaran ujian. Pilihan yang berkaitan dalam fail konfigurasi ditetapkan seperti ini: 🎜rrreeerrreee🎜rrreee🎜

    Anda juga boleh menggunakan persekitaran yang sama sekali berbeza, atau mengatasi mod nyahpepijat lalai ( true ) dengan menghantar pilihan yang berkaitan kepada kaedah createClient(): true ),通过把相关选项传给 createClient() 方法即可:

    rrreee

    如果你的程序需要通过一些HTTP头才能运转,把它们传给createClient()方法的第二个参数:

    rrreee

    你也可以在每一个request基本过程中覆写HTTP header:

    rrreee

    client在 test 测试环境下是容器中的可用服务(或者无论什么环境,只要 framework.test选项被开启)。这意味着只要需要,你可以覆写整个client服务。


    PHPUnit配置 

    每一个程序,有它自己的PHPUnit配置,就存在 app/phpunit.xml.dist 文件中。你可以编辑这个文件,改变默认值,或创建一个仅供你本地机器设定测试选项的 app/phpunit.xml 文件。

    app/phpunit.xml.dist 文件存在你的代码宝库中并且忽略 app/phpunit.xmlrrreee

    Jika anda program memerlukan beberapa pengepala HTTP untuk dijalankan, hantarkannya ke parameter kedua kaedah createClient():
    rrreee

    Anda juga boleh mengatasi pengepala HTTP dalam setiap proses permintaan: rrreee

    klien ialah perkhidmatan yang tersedia dalam bekas dalam persekitaran ujian test (atau tidak kira apa persekitaran, asalkan framework.test didayakan). Ini bermakna anda boleh mengatasi keseluruhan perkhidmatan pelanggan apabila perlu.


    Konfigurasi PHPUnit

    Setiap program mempunyai konfigurasi PHPUnit sendiri, hanya Wujud dalam Fail app/phpunit.xml.dist. Anda boleh mengedit fail ini untuk menukar nilai lalai atau buat fail app/phpunit.xml yang menetapkan pilihan ujian hanya untuk mesin setempat anda.

    Simpan fail app/phpunit.xml.dist dalam repositori anda dan Abaikan Fail app/phpunit.xml.

    🎜Secara lalai, hanya ujian yang disimpan dalam bundle tersuai anda di bawah direktori standard (src/🎜/🎜Bundle/Tests, src/🎜/Bundle/🎜Bundle/Tests, src/*Bundle/Tests) boleh digunakan dengan arahan phpunit. Ini sudah dikonfigurasikan dalam fail app/phpunit.xml.dist: 🎜rrreee🎜 Tetapi anda boleh menambah lebih banyak direktori dengan mudah. Sebagai contoh, konfigurasi berikut menambah ujian dalam lib/ujian direktori tersuai:🎜🎜rrreee🎜Untuk memasukkan direktori lain dalam liputan kod, anda juga perlu menambah 🎜coretan kod:🎜🎜🎜rrreee🎜