Kiểm tra chức năng cơ bản với Crawler của Symfony 2
() translation by (you can also view the original English article)
Kiểm tra các ứng dụng web của bạn là một trong những việc tốt nhất bạn có thể làm để đảm bảo an toàn và bảo mật cho cả ứng dụng và khách truy cập ứng dụng của bạn. Symfony 2 cung cấp một bộ kiểm tra tích hợp hoàn chỉnh mà bạn có thể sử dụng để đảm bảo các ứng dụng của bạn vận hành đúng như bạn mong đợi. Hôm nay chúng ta sẽ xem xét cách mà chúng ta có thể sử dụng Symfony 2 và PHPUnit, framework kiểm tra mà được Symfony 2 sử dụng, để viết các kiểm tra chức năng cơ bản bằng Crawler (trình thu thập thông tin).
Cài đặt
Trước khi chúng tôi có thể bắt đầu bất kỳ hình thức kiểm tra nào, ta cần thiết lập dự án của chúng tôi bằng cách tải xuống framework Symfony 2, cấu hình và sau đó tải PHPUnit xuống.
Cài đặt Symfony 2
Cách tốt nhất để tải xuống Symfony 2 là sử dụng Composer. Nếu bạn chưa biết Composer là gì, hãy chắc chắn kiểm tra một vài bài viết và khóa học Tust+ về nó, chúng sẽ giúp bạn nhanh chóng tăng tốc.
Trước tiên chúng tôi muốn mở Terminal hoặc giao diện dòng lệnh để chúng tôi có thể in ra một vài lệnh composer. Khi ở trong Terminal của bạn, hãy điều hướng đến thư mục gốc của bản phát triển cục bộ của bạn. Đối với tôi, trên OS X, đây sẽ là thư mục ~/Sites
của tôi:
1 |
cd ~/Sites
|
Khi đã ở trong thư mục thích hợp, bây giờ chúng ta có thể sử dụng Composer để tạo dự án Symfony 2 mới, nó sẽ tải về và cài đặt framework cộng với bất kỳ phụ thuộc nào của nó.
1 |
composer create-project symfony/framework-standard-edition crawling/ '~2.5'
|
Lệnh này yêu cầu composer tạo dự án mới bằng cách sử dụng framework Symfony 2 trong thư mục mới tên crawling/
và sau đó chúng tôi cũng chỉ định phiên bản chính xác cần tải xuống, phiên bản ~2.5
. Nếu đây là lần đầu tiên bạn tải framework, thì có thể mất một lúc vì có rất nhiều thư viện để tải xuống cho tất cả các vendor. Vì vậy, bạn có thể muốn nghỉ một chút và quay lại sau vài phút.
Sau khi quá trình tải xuống hoàn tất, Terminal của bạn sẽ hiển thị một trình hướng dẫn tương tác sẽ giúp bạn thiết lập cấu hình. Hướng dẫn tự giải thích, chỉ cần điền thông tin đăng nhập của bạn hoặc để mặc định như tôi đã làm:



Khi bạn nhập thông tin cấu hình của mình, Symfony 2 được tải xuống, cài đặt và sẵn sàng để sử dụng. Bây giờ chúng ta chỉ cần tải PHPUnit để có thể kiểm tra code của mình.
Cài đặt PHPUnit
Để tải xuống PHPUnit, chúng tôi có thể sử dụng lệnh wget trong Terminal của chúng tôi để truy xuất file .phar
hoặc chỉ cần tải xuống từ trang web của họ, tùy bạn:
1 |
wget https://phar.phpunit.de/phpunit.phar |
Với .phar
được tải xuống, bây giờ chúng ta cần điều chỉnh các quyền truy xuất của nó và di chuyển nó đến một vị trí mà Terminal hoặc Command Line và PHP của chúng ta sẽ có quyền truy xuất vào nó. Trên máy của tôi sử dụng OS X, tôi đã chuyển nó vào thư mục /usr/local/bin
của tôi. Tôi cũng đã đổi tên file thành phpunit
vì vậy tôi không phải lo lắng về tiện ích mở rộng khi thử chạy kiểm tra, tiết kiệm chút thời gian:
1 |
chmod +x phpunit.phar
|
2 |
sudo mv phpunit.phar /usr/local/bin/phpunit
|
Bây giờ chúng ta có thể xác minh rằng PHPUnit đã được cài đặt và có thể truy cập thông qua Terminal bằng cách chạy lệnh phpunit
. Bạn sẽ thấy một điều này:



Tạo Crawling bundle (gói thu thập dữ liệu)
Bây giờ chúng tôi cần một bundle để chứa ứng dụng và test code của chúng tôi. Hãy tạo một cái bằng console của Symfony 2, từ Terminal của chúng tôi:
1 |
cd ~/Sites/crawling
|
2 |
php app/console generate:bundle --namespace=Crawling/FtestingBundle --format=yml |
Ở đây, trước tiên chúng tôi thay đổi thư mục vào dự án crawling
của chúng tôi và sau đó sử dụng console để tạo ra bundle mới. Chúng tôi cũng chỉ định Vendor của bundle và tên của bundle này, được phân tách bằng dấu gạch chéo (/
). Cuối cùng, chúng tôi hướng dẫn nó sử dụng YAML làm định dạng cho cấu hình của chúng tôi. Giờ bạn có thể sử dụng bất kỳ định dạng nào bạn muốn nếu bạn không muốn sử dụng YAML và bạn cũng có thể đặt tên cho bundle của mình theo cách bạn muốn, miễn sao trước tiên bạn đặt tên vendor và kết thúc tên bundle của bạn bằng hậu tố Bundle
.
Sau khi chạy lệnh trên, chúng ta lại nhận được một trình hướng dẫn để hoàn tất cài việc đặt bundle. Tôi chỉ nhấn enter cho mỗi dấu nhắc để mặc định vì điều này duy trì toàn bộ quá trình tốt đẹp và đơn giản và giải quyết mọi vấn đề về đường dẫn bằng cách đặt các file của bạn vào các vị trí tùy chỉnh. Đây là một ảnh chụp màn hình của trình hướng dẫn bundle của tôi:



Làm thế nào để chạy kiểm tra của bạn
Ok, chúng tôi đã có Symfony 2, PHPUnit và bundle của chúng tôi; Tôi nghĩ rằng chúng tôi đã sẵn sàng để học cách chạy các bài kiểm tra PHPUnit của chúng tôi cùng với Symfony. Điều đó thực sự rất dễ dàng, chỉ cần thay đổi thư mục vào dự án crawling
của bạn và chạy lệnh phpunit -c app/
để chạy tất cả các kiểm tra của ứng dụng. Bạn sẽ nhận được kết quả sau trong Terminal:



Khi chúng tôi tạo ra bundle, nó cũng tạo ra code mẫu cho chúng tôi. Bài kiểm tra mà bạn thấy đã chạy ở trên là một phần của code mẫu đó. Bạn có thể thấy rằng chúng tôi có một thanh màu xanh lá cây, cho chúng tôi biết rằng các kiểm tra của chúng tôi đã vượt qua. Bây giờ ngay trên Time: 1,97 seconds, chúng tôi cũng có một dấu chấm duy nhất cho chúng tôi thấy rằng chỉ có một bài kiểm tra đã được chạy. Trong thanh màu xanh lá cây, chúng tôi có trạng thái OK cũng thể hiện có bao nhiêu bài kiểm tra và xác nhận đã được chạy.
Do đó bằng cách chỉ chạy một lệnh này, chúng tôi biết rằng ứng dụng Symfony 2 của chúng tôi đã được cài đặt, chạy đúng và được kiểm tra!
Tạo Controller, Template và Route
Bây giờ chúng ta cần một số code ứng dụng thực tế để có thể kiểm tra.
Controller
Hãy bắt đầu bằng cách tạo một class Controller mới và controller action. Bên trong dự án crawling
của bạn, trong src/Crawling/FtestingBundle/Controller
, tạo một file mới có tên CrawlingControll.php
và bổ sung đoạn sau vào đó:
1 |
<?php
|
2 |
|
3 |
namespace Crawling\FtestingBundle\Controller; |
4 |
|
5 |
use Symfony\Bundle\FrameworkBundle\Controller\Controller; |
6 |
|
7 |
class CrawlingController extends Controller { |
8 |
|
9 |
}
|
Trong file này, chúng ta chỉ định nghĩa cấu trúc class controller, mang đến cho nó namespace thích hợp và bao gồm class cha của Controller
.
Action của Controller
Bên trong class của chúng ta, bây giờ hãy xác định hai controller action đơn giản của chúng ta. Họ sẽ chỉ hiển thị hai trang khác nhau: trang home
và trang other
:
1 |
public function homeAction() { |
2 |
return $this->render('CrawlingFtestingBundle:Crawling:home.html.twig'); |
3 |
}
|
4 |
|
5 |
public function otherAction() { |
6 |
return $this->render('CrawlingFtestingBundle:Crawling:other.html.twig'); |
7 |
}
|
Các template
Bây giờ chúng ta cần tạo các file mẫu cho các controller action này. Trong src/Crawling/Ftesting/Resources/view
, hãy tạo một thư mục mới có tên Crawling
để giữ các file template của CrawlingController
của chúng tôi. Trong thư mục này, trước tiên hãy tạo file home.html.twig
, với HTML sau bên trong:
1 |
<h1>Crawling Home Page</h1> |
2 |
|
3 |
<p>Here's our crawling home page.</p> |
4 |
|
5 |
<p>Please visit <a href="{{ path('crawling_other') }}">this other page</a> too!</p> |
File chỉ gồm HTML cơ bản và liên kết đến trang other
.
Bây giờ cũng tiếp tục tạo file other.html.twig
, thêm HTML này vào:
1 |
<h1>Other Page</h1> |
2 |
|
3 |
<p>Here's another page, which was linked to from our home page, just for testing purposes.</p> |
Các Route
Cuối cùng, với code ứng dụng của chúng tôi, hãy xác định các route cho hai trang này. Mở src/Crawling/FtestingBundle/Resources/config/định.yml
và nhập vào hai route sau, bên dưới route mặc định được tạo ra đi kèm với file route của chúng tôi:
1 |
crawling_home: |
2 |
path: /crawling/home |
3 |
defaults: { _controller: CrawlingFtestingBundle:Crawling:home } |
4 |
|
5 |
crawling_other: |
6 |
path: /crawling/other |
7 |
defaults: { _controller: CrawlingFtestingBundle:Crawling:other } |
Ở đây tôi xác định hai route, một route cho mỗi controller action của chúng tôi. Chúng tôi bắt đầu với tên route mà có thể sử dụng trong các liên kết, v.v. và sau đó chúng tôi xác định đường dẫn route là URI của nó để truy cập trang trong trình duyệt và sau đó chúng tôi sẽ hướng dẫn controller nào nên áp dụng với nó.
Bây giờ hãy nhớ trong YAML bạn không muốn sử dụng bất kỳ tab nào, luôn sử dụng khoảng trắng hoặc các route của bạn sẽ không hoạt động!
Do đó chỉ với hai trang này, ngay cả khi chúng cơ bản và tĩnh như thế nào, chúng ta vẫn có thể tìm hiểu rất nhiều về cách sử dụng Crawler của Symfony 2 để kiểm tra xem toàn bộ có controller, template, route và liên kết có hoạt động như một tích hợp toàn bộ (một bài kiểm tra chức năng - functional test), cũng như đảm bảo các trang của chúng tôi hiển thị cấu trúc HTML chính xác.
Viết kiểm tra chức năng - functional test
Bây giờ chúng tôi đã sẵn sàng để bắt đầu tìm hiểu cách viết các bài kiểm tra chức năng bằng Crawler. Đầu tiên, chúng tôi sẽ tạo một file test.
Tạo file test của chúng tôi
Tất cả các kiểm tra của bạn trong Symfony 2, các kiểm tra PHPUnit đều được lưu trữ thư mục Tests/Controller
của bạn, mỗi controller nên có file kiểm tra controller riêng được đặt tên theo class controller mà nó đang kiểm tra. Vì chúng tôi có CrawlingController
, chúng tôi sẽ cần tạo file CrawlingControllTest.php
bên trong src/Crawling/FtestingBundle/Tests/Controller
, với định nghĩa của class sau đây:
1 |
<?php
|
2 |
|
3 |
namespace Crawling\FtestingBundle\Tests\Controller; |
4 |
|
5 |
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; |
6 |
|
7 |
class CrawlingControllerTest extends WebTestCase |
8 |
{
|
9 |
|
10 |
}
|
Ở đây, chúng tôi đặt tên cho test của chúng tôi và sau đó đưa vào parent class WebTestCase cho chúng tôi chức năng kiểm tra PHPUnit của chúng tôi. Class kiểm tra của chúng tôi được đặt tên chính xác giống như tên file của chúng tôi và mở rộng parent class WebTestCase để kế thừa các tính năng của nó.
Bây giờ, hãy tạo một phương thức test để giữ các xác nhận mà chúng tôi sẽ thực hiện để kiểm tra trang home của chúng tôi. Bên trong test class, hãy tạo phương thức sau:
1 |
public function testHome() { |
2 |
|
3 |
}
|
Bất cứ khi nào bạn tạo một phương thức kiểm tra bằng PHPUnit trong Symfony 2, chúng tôi luôn đặt tiền tố tên phương thức của mình bằng từ test. Bạn có thể tự đặt bất kỳ tên nào cho phương thức theo ý bạn, mặc dù quy ước là đặt tên theo controller action mà bạn đang kiểm tra. Do đó tôi đã đặt tên testHome
để tuân theo quy ước đó.
Client
Bây giờ bên trong phương thức test của chúng tôi, chúng tôi cần phương pháp để mô phỏng trình duyệt để chúng tôi có thể gửi yêu cầu HTTP cho một trong các route của mình và kiểm tra xem mọi thứ có hoạt động như chúng tôi mong đợi hay không. Để làm điều này, chúng ta sẽ tạo một object client (máy khách) bằng cách gọi một phương thức createClient()
:
1 |
$client = static::createClient(); |
Bây giờ chúng ta có thể sử dụng object $client
này để thực hiện yêu cầu HTTP đó và bắt đầu sử dụng Crawler.
Crawler
Crawler là cốt lõi (core) của functional test trong Symfony 2 và cho phép chúng tôi duyệt và thu thập thông tin về trang của ứng dụng web của mình, cũng như thực hiện các hành động như nhấp vào liên kết hoặc gửi form. Hãy xác định đối tượng Crawler của chúng tôi bằng cách thực hiện yêu cầu HTTP bằng ứng dụng client. Thêm quyền sau vào đối tượng $client
của bạn, trong phương thức testHome
của bạn:
1 |
$crawler = $client->request('GET', '/crawling/home'); |
Phương thức này sẽ trả về một đối tượng Crawler để kiểm tra trang home của chúng tôi. Đôí tượng này sẽ cho chúng tôi biết rằng trang của chúng tôi tồn tại, nó có HTML và định dạng chính xác và controller, template và route hoạt động cùng nhau như một đơn vị.
Kiểm tra Heading & Paragraph
Để bắt đầu functional test, chúng tôi muốn khẳng định rằng trang chủ của chúng tôi chứa heading phù hợp với nội dung phù hợp bên trong nó. Chúng tôi sử dụng đối tượng trình $crawler
và các phương thức khác nhau của nó để làm điều này. Tất cả các phương thức này sẽ trả lại một đối tượng Crawler khác có chứa phản hồi của trang được kiểm tra thực tế. Sau đó, chúng tôi sẽ kiểm tra phản hồi này để đảm bảo mọi thứ như mong đợi.
Thêm code sau vào phương thức testHome
của bạn:
1 |
$heading = $crawler->filter('h1')->eq(0)->text(); |
2 |
$this->assertEquals('Crawling Home Page', $heading); |
Chúng tôi bắt đầu bằng cách gọi phương thức filter()
của đối tượng $crawler
của chúng tôi để lọc phản hồi của trang và chọn tất cả các phần tử h1
. Sau đó chúng ta có thể xâu chuỗi các lần gọi phương thức khác để lọc lựa chọn của chúng ta nhiều hơn nữa. Ở đây tôi sử dụng phương thức eq()
nhận vị trí index của phần tử h1 mà chúng ta muốn chọn. Tôi chọn index 0
, heading đầu tiên. Cuối cùng, tôi xâu chuỗi (chain) lần gọi phương thức text, sẽ trả về nội dung văn bản của phần tử HTML này và lưu kết quả vào biến $heading.
Sau khi lọc phần tử h1 mà chúng tôi muốn kiểm tra, bây giờ chúng tôi cần xác nhận rằng chúng tôi có phần tử chính xác. Thực hiện điều này bằng cách sử dụng phương thức assertEquals()
nhận làm đối số đầu tiên mà giá trị của heading và đối số thứ hai là giá trị thực của phản hồi được trả về, chính là $title của chúng tôi. Bằng cách này, chúng tôi sẽ biết rằng chúng tôi đang ở đúng trang, nếu nội dung phù hợp với điều mong đợi.
Chạy Heading Test
Do đó chỉ với bốn dòng code PHP đơn giản, chúng tôi sẽ có thể kiểm tra controller, template và route. Hãy chạy kiểm tra của chúng tôi để đảm bảo nó vượt qua. Trong Terminal của bạn, từ trong dự án Symfony crawling
của bạn, hãy chạy phpunit -c app/
. Bạn nên xem phần sau đây:



Bây giờ chúng tôi có hai bài kiểm tra và hai xác nhận, tất cả đều được thành công! Bây giờ bạn có thể kiểm tra paragraph bên dưới heading theo cách tương tự, nhưng lần này chúng ta sẽ sử dụng phương thức first()
:
1 |
$para1 = $crawler->filter('p')->first()->text(); |
2 |
$this->assertEquals("Here's our crawling home page.", $para1); |
Nếu bạn chạy lại test của mình, giờ chúng tôi có ba xác nhận thành công. Tốt lắm!
Kiểm tra việc click vào liên kết
Bây giờ hãy thử kiểm tra quá trình nhấp vào liên kết trang khác này của chúng tôi. Nó sẽ đưa chúng ta đến trang khác và hiển thị nội dung phù hợp ở đó. Thêm đoạn code sau vào phương thức testHome
của bạn:
1 |
$link = $crawler->filter('a:contains("this other page")')->first()->link(); |
2 |
$otherPage = $client->click($link); |
3 |
$this->assertEquals('Other Page', $otherPage->filter('h1')->first()->text()); |
Chúng tôi bắt đầu bằng cách lọc trang home của chúng tôi bằng một thẻ a
. Chúng tôi sử dụng phương thức bộ lọc :container()
để lọc các thẻ theo a
nội dung của chúng để đảm bảo chọn đúng liên kết. Sau đó, chúng tôi chỉ cần xâu chuỗi phương thức first()
để lấy phương thức đầu tiên và gọi phương thức link()
trên đó để tạo một đối tượng liên kết để chúng tôi có thể mô phỏng việc nhấp vào liên kết bằng cách dùng $client
.
Bây giờ chúng ta có một đối tượng $link
, chúng ta cần nhấp vào nó, bằng cách gọi phương thức click()
của đối tượng $client
và chuyển đối tượng $link
đến đối tượng đó và lưu trữ phản hồi vào biến $otherPage
. Điều này cũng giống như bất kỳ đối tượng Crawler nào khác, phương thức click trả về phản hồi. Rất dễ!
Và cuối cùng, chúng tôi chỉ xác nhận rằng nội dung heading của $otherPage
của chúng tôi tương đương với điều chúng tôi mong đợi khi sử dụng phương thức assertEquals()
. Nếu có, chúng tôi biết rằng liên kết của chúng tôi hoạt động!
Chạy test thêm một lần nữa!
Bây giờ chúng ta hãy chạy test lần cuối cùng để đảm bảo rằng liên kết của chúng tôi hoạt động chính xác và chúng tôi đang ở đúng trang sau khi nhấp vào nó. Đây là kết quả Terminal của tôi:



Chúng tôi có hai test và 4 xác nhận, tất cả đều được thông qua. Ứng dụng hoàn tất!
Tổng kết
Và thế đấy. Chúng tôi đã kiểm tra rằng controller, các controller action, template và route đều hoạt động cùng nhau và chúng tôi biết rằng HTML và nội dung cho từng thành phần đang hiển thị đúng trên trang, cũng như liên kết của chúng tôi đến vị trí thích hợp. Công việc đã hoàn thành tốt.
Giờ tôi khuyến khích bạn hãy thử những điều bạn đã học bằng cách kiểm tra trang other, bổ sung nhiều HTML hoặc liên kết đến nó và nói chung chỉ cần cảm nhận về việc sử dụng Crawler để đảm bảo trang của bạn hoạt động như mong đợi.