Students Save 30%! Learn & create with unlimited courses & creative assets Students Save 30%! Save Now
Advertisement
  1. Code
  2. Laravel
Code

Laravel, BDD và bạn: khởi đầu

by
Difficulty:IntermediateLength:LongLanguages:
This post is part of a series called Laravel, BDD And You.
Laravel, BDD and You: The First Feature

Vietnamese (Tiếng Việt) translation by Andrea Ho (you can also view the original English article)

Chào mừng bạn đến với loạt bài về việc phát triển các ứng dụng Laravel bằng cách sử dụng phương pháp phát triển dựa trên hành vi - behavior-driven (BDD). Full stack BDD nghe có vẻ phức tạp và đáng sợ. Cũng như việc có nhiều nhà phát triển, có nhiều cách để triển khai phương pháp này.

Trong loạt bài này, tôi sẽ hướng dẫn bạn cách tiếp cận của tôi về việc sử dụng Behat và PhpSpec để thiết kế một ứng dụng Laravel từ đầu.

Có rất nhiều tài nguyên về BDD nói chung, nhưng tài liệu cụ thể của Laravel rất khó tìm. Do đó, trong loạt bài này, chúng tôi sẽ tập trung nhiều hơn vào các khía cạnh liên quan đến Laravel và ít đề cập đến những thứ chung mà bạn có thể tìm đọc từ nhiều nơi khác.

Mô tả về hành vi

Khi mô tả hành vi, còn được gọi là viết nên các câu chuyện và thông số kỹ thuật, chúng ta sẽ sử dụng cách tiếp cận outside-in (từ ngoài vào trong). Điều này có nghĩa là mỗi khi xây dựng một tính năng mới, chúng tôi sẽ bắt đầu bằng cách viết câu chuyện tổng thể của người dùng. Điều này thường xuất phát từ góc nhìn của khách hàng hoặc các bên liên quan.

Chúng ta đang mong đợi điều gì xảy ra khi thực hiện điều này?

Chúng tôi không được phép viết bất kỳ code nào cho đến khi chúng tôi có một rắc rối hoặc thất bại, ngoại trừ khi chúng tôi đang tái cấu trúc code hiện có.

Đôi khi, sẽ cần phải lặp đi liên tục lặp lại giải quyết một phần nhỏ của một câu chuyện hoặc tính năng (hai từ mà tôi sử dụng thay thế cho nhau) mà chúng tôi đang làm việc. Điều này thường nghĩa là viết thông số kỹ thuật với PhpSpec. Đôi khi, sẽ lần lặp lại nhiều lại ở cấp độ interation (tích hợp) hoặc unit (đơn vị) trước khi toàn bộ câu chuyện (ở acceptance level) được thông qua. Tất cả điều này nghe có vẻ rất phức tạp nhưng thực sự thì không. Tôi là một người có niềm tin to lớn vào việc học qua thực hành, vì vậy tôi nghĩ rằng mọi thứ sẽ có dễ hiểu hơn khi chúng ta bắt đầu viết code thực tế.

Chúng tôi sẽ viết các câu chuyện và thông số kỹ thuật ở 4 cấp độ khác nhau:

1. Acceptance

Hầu hết thời gian, nhóm chức năng của chúng tôi sẽ hoạt động như acceptance layer của chúng tôi. Cách chúng tôi sẽ mô tả các tính năng của chúng tôi trong nhóm chức năng sẽ rất giống với cách viết các câu chuyện acceptance (sử dụng framework trình duyệt tự động) và như vậy sẽ sinh ra nhiều sự trùng lặp.

Miễn là những câu chuyện mô tả hành vi theo góc độ của khách hàng, chúng đóng vai trò là những câu chuyện acceptance (chấp nhận). Chúng tôi sẽ sử dụng Symfony DomCrawler để kiểm tra kết quả của ứng dụng của chúng tôi. Sau đó, chúng ta có thể thấy rằng chúng ta cần kiểm tra thông qua một trình duyệt thực tế có thể chạy JavaScript. Kiểm tra thông qua trình duyệt tạo ra một số mối quan tâm mới, vì chúng tôi cần đảm bảo rằng chúng tôi tải môi trường kiểm tra khi nhóm chức năng chạy.

2. Chức năng

Trong nhóm chức năng của chúng tôi, chúng tôi sẽ có quyền truy xuất vào ứng dụng Laravel, rất thuận tiện. Trước hết, nó giúp bạn dễ dàng phân biệt giữa các môi trường. Thứ hai, không thông qua trình duyệt làm cho test của chúng tôi nhanh hơn rất nhiều. Bất cứ khi nào chúng tôi muốn thực hiện một tính năng mới, chúng tôi sẽ viết một câu chuyện trong nhóm chức năng của chúng tôi bằng Behat.

3. Tích hợp

Nhóm tích hợp của chúng tôi sẽ kiểm tra hành vi của phần cốt lõi trong ứng dụng của chúng tôi mà không nhất thiết phải có quyền truy xuất vào Laravel. Nhóm tích hợp thường sẽ là tổng hợp của các câu chuyện Behat và thông số kỹ thuật PhpSpec.

4. Unit

Các unit test của chúng tôi sẽ được viết bằng PhpSpec và sẽ kiểm tra các đơn vị nhỏ tách biệt của lõi ứng dụng. Các thực thể của chúng ta, các đối tượng giá trị, vv tất cả sẽ có thông số kỹ thuật.

Tinh huống

Trong suốt loạt bài này, bắt đầu từ bài viết tiếp theo, chúng tôi sẽ xây dựng một hệ thống để theo dõi thời gian. Chúng tôi sẽ bắt đầu bằng cách mô tả hành vi từ bên ngoài bằng cách viết các tính năng Behat. Hành vi nội bộ của ứng dụng của chúng tôi sẽ được mô tả bằng PhpSpec.

Hai công cụ này sẽ giúp chúng tôi cảm thấy thoải mái với chất lượng của ứng dụng chúng tôi đang xây dựng. Chúng tôi chủ yếu sẽ viết các tính năng và thông số kỹ thuật trên ba cấp độ:

  1. Functional - chức năng
  2. Integration - tích hợp
  3. Unit


Trong nhóm chức năng của chúng tôi, chúng tôi sẽ thu thập các phản hồi HTTP của ứng dụng ở chế độ không header, nghĩa là chúng tôi sẽ dùng trình duyệt. Điều này sẽ giúp việc tương tác với Laravel dễ dàng hơn và làm cho nhóm chức năng của chúng tôi cũng đóng vai trò là acceptance layer của chúng tôi.

Sau này, nếu chúng ta cho ra kết quả là một giao diện người dùng phức tạp hơn và có thể cần phải kiểm tra một số JavaScript thì chúng ta có thể thêm một nhóm acceptance đặc trưng. Loạt bài này vẫn đang được viết, vì vậy hãy để lại các đề xuất của bạn trong phần bình luận.

Thiết lập của chúng tôi

Lưu ý rằng với hướng dẫn này, tôi giả sử bạn có một bản cài đặt mới của Laravel (4.2). Tốt nhất là bạn cũng đang sử dụng Laravel Homestead, đó là những gì tôi đã dùng khi tôi viết code này.

Trước khi chúng tôi bắt đầu công việc thực tế, hãy đảm bảo rằng chúng tôi có Behat và PhpSpec đang vận hành. Mặc dù vậy, trước tiên, tôi muốn dọn dẹp một chút mỗi khi tôi bắt đầu một dự án laravel mới và xóa những thứ tôi không cần:

Nếu bạn xóa các file này, đảm bảo cập nhật file composer.json cho phù hợp:

Và dĩ nhiên:

Bây giờ chúng tôi đã sẵn sàng để tải về các công cụ BDD mà chúng tôi cần. Chỉ cần thêm phần yêu cầu-dev vào composer.json của bạn:

"Tại sao chúng ta lại tải về PHPUnit?" bạn có thể đang suy nghĩ? Chúng tôi sẽ không viết các trường hợp thử nghiệm PHPUnit tốt trong loạt bài này, nhưng khẳng định chúng là một công cụ hữu ích cùng với Behat. Chúng ta sẽ thấy điều đó sau trong bài viết này khi chúng ta viết tính năng đầu tiên của chúng tôi.

Hãy nhớ cập nhật các phụ thuộc sau khi sửa đổi composer.json:

Chúng tôi gần như đã hoàn tất việc cài đặt và thiết lập công cụ. PhpSpec hoạt động tốt:

Nhưng Behat cần triển khai nhanh chóng với tùy chọn --init để thiết lập mọi thứ:

Lệnh đầu tiên tạo ra một class FeatureContext mới, nơi chúng ta có thể viết các định nghĩa bước cần thiết cho các tính năng của mình:

Viết tính năng đầu tiên của chúng tôi

Tính năng đầu tiên của sẽ rất đơn giản: chỉ đơn giản là đảm bảo rằng bản cài đặt Laravel mới của chúng tôi chào đón chúng tôi bằng câu "You have arrived". trên trang chủ. Tôi cũng đưa ra bước Given khá ngớ ngẫn, Given I am logged in, chỉ cho thấy mức độ tương tác dễ dàng với Laravel trong các tính năng của chúng tôi.

Về mặt kỹ thuật, tôi sẽ phân loại loại tính năng này là một functional test, vì nó tương tác với framework, nhưng nó cũng đóng vai trò là một acceptance test, vì chúng tôi sẽ không thấy bất kỳ kết quả nào khác khi chạy test tương tự thông qua một công cụ trình duyệt kiểm tra. Từ bây giờ chúng tôi sẽ bám sát nhóm functional test của chúng tôi.

Hãy tiếp tục tạo một file welcome.feature và đưa vào features/functional:

Bằng cách đưa vào các tính năng chức năng trong một thư mục functional, chúng ta sẽ dễ dàng quản lý các nhóm của mình sau này. Chúng tôi không muốn các tính năng kiểu tích hợp không yêu cầu Laravel phải chờ đợi nhóm chức năng chậm chạp.

Tôi thích mọi thứ tốt và gọn gàng, vì vậy tôi tin rằng chúng ta nên có một bối cảnh tính năng dành riêng cho nhóm chức năng có thể cho phép chúng ta truy cập vào Laravel. Bạn có thể tiếp tục sao chép file FeatureContext hiện có và thay đổi tên class thành LaravelFeatureContext. Để làm việc này, chúng ta cũng cần một file cấu hình Behat.yml.

Tạo một trong thư mục gốc của dự án của bạn và thêm nội dung như sau:

Tôi nghĩ rằng YAML ở đây là khá dễ hiểu. Nhóm chức năng của chúng tôi sẽ tìm kiếm các tính năng trong thư mục functional và chạy chúng thông qua LaravelFeatureContext.

Nếu chúng ta cố gắng chạy Behat tại thời điểm này, nó sẽ chỉ chúng ta thực hiện các định nghĩa bước cần thiết. Chúng ta có thể yêu cầu Behat thêm các phương thức scaffold mới vào LaravelFeatureContext bằng lệnh sau:

Và bây giờ, như bạn có thể thấy từ kết quả, chúng tôi đã sẵn sàng để bắt đầu thực hiện bước đầu tiêni: Given am logged in.

Trường hợp test của PHPUnit gửi cùng với Laravel cho phép chúng tôi thực hiện các công cụ như $this->be($user), đăng nhập vào một người dùng nhất định. Cuối cùng, chúng tôi muốn có thể tương tác với Laravel như thể chúng tôi đang sử dụng PHPUnit, vì vậy hãy tiếp tục viết code định nghĩa bước "we wish we had":

Tất nhiên, code này sẽ không hiệu quả, vì Behat không biết cụ thể gì về Laravel, nhưng tôi sẽ chỉ cho bạn thấy ngay sẽ dễ dàng như thế nào để Behat và Laravel kết thân với nhau.

Nếu bạn xem mã nguồn của Laravel và tìm thấy class Illuminate\Foundation\Testing\TestCase, trường hợp kiểm thử mặc định mở rộng từ class này, bạn sẽ thấy rằng bắt đầu từ Laravel 4.2, mọi thứ đã được chuyển thành trait. ApplicationTrait hiện chịu trách nhiệm khởi động một phiên bản Application, thiết lập ứng dụng khách HTTP và cung cấp cho chúng tôi một vài phương thức helper, chẳng hạn như be().

Điều này khá thú vị, chủ yếu vì nghĩa là chúng ta có thể tải nó về vào bối cảnh Behat của chúng ta mà hầu như không cần thiết lập. Chúng tôi cũng có quyền truy xuất vào AssertionsTrait, nhưng vẫn được gắn với PHPUnit.

Khi chúng ta tải về trait, chúng ta cần làm 2 việc. Chúng ta cần có một phương thức setUp(), giống như phương thức trong class Illuminate\Foundation\Testing\TestCase và chúng ta cần một phương thức createApplication(), giống như phương thức trong trường hợp kiểm tra mặc định của Laravel. Trên thực tế chúng ta chỉ có thể sao chép hai phương thức đó và trực tiếp sử dụng chúng.

Chỉ có một điều cần chú ý: Trong PHPUnit, phương thức setUp() sẽ tự động được gọi trước mỗi bài test. Để đạt được điều tương tự trong Behat, chúng ta có thể sử dụng chú thích @BeforeScenario.

Thêm phần sau đây vào LaravelFeatureContext của bạn:

Khá dễ dàng và xem kết quả chúng tôi nhận được khi chạy Behat:

Bước đầu tiên xanh, có nghĩa là thiết lập của chúng tôi đã xong!

Tiếp theo, chúng ta có thể thực hiện bước When I visit. Cách này cực dễ và chúng ta chỉ cần sử dụng phương thức call() ApplicationTrait cung cấp. Một dòng code sẽ tạo ra kết quả đó:

Bước cuối cùng, Then I should see, mất thêm một chút thời gian và chúng ta cần phải tải về hai phụ thuộc. Chúng tôi sẽ cần PHPUnit để xác nhận và chúng tôi sẽ cần Symfony DomCrawler để tìm kiếm văn bản "You have arrived".

Chúng ta có thể triển khai như thế này:

Nó khá giống với code bạn sẽ viết nếu bạn đang sử dụng PHPUnit. Phần filterXpath() hơi khó hiểu và chúng tôi sẽ nghĩ nhiều với nó lúc này, vì nó nằm ngoài phạm vi của bài viết này. Chỉ cần tin tôi rằng nó hoạt động.

Việc lần nữa chạy Behat là một tin tốt:

Tính năng này hoạt động như mong đợi và nhà phát triển được chào đón khi đến nơi.

Tổng kết

Hiện tại, LaravelFeatureContext hoàn chỉnh sẽ trông giống như thế này:

Bây giờ chúng tôi có một nền tảng thực sự tốt để xây dựng khi chúng tôi tiếp tục phát triển ứng dụng Laravel mới của mình bằng cách sử dụng BDD. Tôi hy vọng tôi đã chứng minh cho bạn thấy thật dễ dàng để khiến Laravel và Behat chơi thân với nhau.

Chúng tôi đã đề cập vào rất nhiều chủ đề khác nhau trong bài viết đầu tiên này. Không cần phải lo lắng, chúng tôi sẽ xem xét kỹ hơn về mọi thứ khi loạt bài tiếp tục. Nếu bạn có bất kỳ câu hỏi hoặc đề xuất nào, xin vui lòng để lại bình luận.

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.