diff --git a/1-js/03-code-quality/05-testing-mocha/3-pow-test-wrong/solution.md b/1-js/03-code-quality/05-testing-mocha/3-pow-test-wrong/solution.md index 4d0571b9d..46715d863 100644 --- a/1-js/03-code-quality/05-testing-mocha/3-pow-test-wrong/solution.md +++ b/1-js/03-code-quality/05-testing-mocha/3-pow-test-wrong/solution.md @@ -1,49 +1,49 @@ -The test demonstrates one of the temptations a developer meets when writing tests. +Bài kiểm tra thể hiện một trong những cám dỗ mà nhà phát triển gặp phải khi viết bài kiểm tra. -What we have here is actually 3 tests, but layed out as a single function with 3 asserts. +Những gì chúng ta có ở đây thực sự là 3 bài kiểm tra, nhưng được bố trí dưới dạng một hàm duy nhất với 3 lần xác nhận. -Sometimes it's easier to write this way, but if an error occurs, it's much less obvious what went wrong. +Đôi khi viết theo cách này dễ dàng hơn, nhưng nếu có lỗi xảy ra, thì sẽ khó nhận ra điều gì đã xảy ra. -If an error happens in the middle of a complex execution flow, then we'll have to figure out the data at that point. We'll actually have to *debug the test*. +Nếu xảy ra lỗi ở giữa quy trình thực thi phức tạp, thì chúng ta sẽ phải tìm ra dữ liệu tại thời điểm đó. Chúng ta thực sự sẽ phải *gỡ lỗi cho bài kiểm tra*. -It would be much better to break the test into multiple `it` blocks with clearly written inputs and outputs. +Sẽ tốt hơn nhiều nếu chia bài kiểm tra thành nhiều khối `it` với đầu vào và đầu ra được viết rõ ràng. -Like this: +Như thế này: ```js -describe("Raises x to power n", function() { - it("5 in the power of 1 equals 5", function() { +describe("Nâng x lên luỹ thừa n", function() { + it("5 mũ 1 bằng 5", function() { assert.equal(pow(5, 1), 5); }); - it("5 in the power of 2 equals 25", function() { + it("5 mũ 2 bằng 25", function() { assert.equal(pow(5, 2), 25); }); - it("5 in the power of 3 equals 125", function() { + it("5 mũ 3 bằng 125", function() { assert.equal(pow(5, 3), 125); }); }); ``` -We replaced the single `it` with `describe` and a group of `it` blocks. Now if something fails we would see clearly what the data was. +Chúng ta đã thay thế một khối `it` bằng `describe` và một nhóm các khối `it`. Bây giờ nếu có gì đó không thành công, chúng ta sẽ thấy rõ ràng dữ liệu là gì. -Also we can isolate a single test and run it in standalone mode by writing `it.only` instead of `it`: +Ngoài ra, chúng ta có thể tách riêng một bài kiểm tra và chạy nó ở chế độ độc lập bằng cách viết `it.only` thay vì `it`: ```js -describe("Raises x to power n", function() { - it("5 in the power of 1 equals 5", function() { +describe("Nâng x lên luỹ thừa n", function() { + it("5 mũ 1 bằng 5", function() { assert.equal(pow(5, 1), 5); }); *!* - // Mocha will run only this block - it.only("5 in the power of 2 equals 25", function() { + // Mocha sẽ chỉ chạy block này + it.only("5 mũ 2 bằng 25", function() { assert.equal(pow(5, 2), 25); }); */!* - it("5 in the power of 3 equals 125", function() { + it("5 mũ 3 bằng 125", function() { assert.equal(pow(5, 3), 125); }); }); diff --git a/1-js/03-code-quality/05-testing-mocha/3-pow-test-wrong/task.md b/1-js/03-code-quality/05-testing-mocha/3-pow-test-wrong/task.md index 66fece09a..d33e45f2b 100644 --- a/1-js/03-code-quality/05-testing-mocha/3-pow-test-wrong/task.md +++ b/1-js/03-code-quality/05-testing-mocha/3-pow-test-wrong/task.md @@ -2,12 +2,12 @@ importance: 5 --- -# What's wrong in the test? +# Có gì sai trong bài kiểm tra? -What's wrong in the test of `pow` below? +Có gì sai trong bài kiểm tra `pow` bên dưới? ```js -it("Raises x to the power n", function() { +it("Nâng x lên luỹ thừa n", function() { let x = 5; let result = x; @@ -21,4 +21,4 @@ it("Raises x to the power n", function() { }); ``` -P.S. Syntactically the test is correct and passes. +Tái bút: Về mặt cú pháp, bài kiểm tra là chính xác và đỗ. diff --git a/1-js/03-code-quality/05-testing-mocha/article.md b/1-js/03-code-quality/05-testing-mocha/article.md index 68ffcae4d..071f396ad 100644 --- a/1-js/03-code-quality/05-testing-mocha/article.md +++ b/1-js/03-code-quality/05-testing-mocha/article.md @@ -1,147 +1,147 @@ -# Automated testing with Mocha +# Kiểm tra tự động với Mocha -Automated testing will be used in further tasks, and it's also widely used in real projects. +Kiểm tra tự động sẽ được sử dụng trong các tác vụ tiếp theo và nó cũng được sử dụng rộng rãi trong các dự án thực tế. -## Why we need tests? +## Tại sao chúng ta cần kiểm tra? -When we write a function, we can usually imagine what it should do: which parameters give which results. +Khi chúng ta viết một hàm, chúng ta thường có thể hình dung nó sẽ làm gì: tham số nào cho kết quả nào. -During development, we can check the function by running it and comparing the outcome with the expected one. For instance, we can do it in the console. +Trong quá trình phát triển, chúng ta có thể kiểm tra hàm bằng cách chạy nó và so sánh kết quả với kết quả mong đợi. Chẳng hạn, chúng ta có thể làm điều đó trong bảng điều khiển. -If something is wrong -- then we fix the code, run again, check the result -- and so on till it works. +Nếu có điều gì sai -- thì ta sửa mã, chạy lại, kiểm tra kết quả -- và cứ thế cho đến khi nó hoạt động. -But such manual "re-runs" are imperfect. +Nhưng "chạy lại" thủ công như vậy là không hoàn hảo. -**When testing a code by manual re-runs, it's easy to miss something.** +**Khi kiểm tra mã bằng cách chạy lại thủ công, rất dễ bỏ sót điều gì đó.** -For instance, we're creating a function `f`. Wrote some code, testing: `f(1)` works, but `f(2)` doesn't work. We fix the code and now `f(2)` works. Looks complete? But we forgot to re-test `f(1)`. That may lead to an error. +Chẳng hạn, chúng ta đang tạo một hàm `f`. Ta đã viết một số mã, thử nghiệm: `f(1)` hoạt động, nhưng `f(2)` không hoạt động. Chúng ta sửa mã và bây giờ `f(2)` hoạt động. Có vẻ hoàn chỉnh? Nhưng chúng ta đã quên kiểm tra lại `f(1)`. Điều đó có thể dẫn đến một lỗi. -That's very typical. When we develop something, we keep a lot of possible use cases in mind. But it's hard to expect a programmer to check all of them manually after every change. So it becomes easy to fix one thing and break another one. +Điều đó rất điển hình. Khi chúng ta phát triển một thứ gì đó, chúng ta ghi nhớ rất nhiều trường hợp sử dụng có thể xảy ra. Nhưng thật khó để mong đợi một lập trình viên kiểm tra tất cả chúng một cách thủ công sau mỗi lần thay đổi. Vì vậy, nó trở nên dễ dàng để sửa chữa một thứ và phá vỡ một thứ khác. -**Automated testing means that tests are written separately, in addition to the code. They run our functions in various ways and compare results with the expected.** +**Kiểm tra tự động có nghĩa là các kiểm tra được viết riêng, bên cạnh mã. Chúng chạy các hàm của chúng ta theo nhiều cách khác nhau và so sánh kết quả với kết quả mong đợi.** ## Behavior Driven Development (BDD) -Let's start with a technique named [Behavior Driven Development](http://en.wikipedia.org/wiki/Behavior-driven_development) or, in short, BDD. +Hãy bắt đầu với một kỹ thuật có tên [Behavior Driven Development](http://en.wikipedia.org/wiki/Behavior-driven_development) hoặc, ngắn gọn, BDD. -**BDD is three things in one: tests AND documentation AND examples.** +****BDD là ba thứ trong một: kiểm tra VÀ tài liệu VÀ ví dụ.** -To understand BDD, we'll examine a practical case of development. +Để hiểu BDD, chúng ta sẽ xem xét một trường hợp phát triển thực tế. -## Development of "pow": the spec +## Phát triển "pow": thông số kỹ thuật -Let's say we want to make a function `pow(x, n)` that raises `x` to an integer power `n`. We assume that `n≥0`. +Giả sử chúng ta muốn tạo một hàm `pow(x, n)` nâng `x` lên một lũy thừa nguyên `n`. Chúng ta giả định rằng `n≥0`. -That task is just an example: there's the `**` operator in JavaScript that can do that, but here we concentrate on the development flow that can be applied to more complex tasks as well. +Tác vụ đó chỉ là một ví dụ: có toán tử `**` trong JavaScript có thể làm điều đó, nhưng ở đây chúng ta tập trung vào quy trình phát triển cũng có thể được áp dụng cho các tác vụ phức tạp hơn. -Before creating the code of `pow`, we can imagine what the function should do and describe it. +Trước khi tạo mã của `pow`, chúng ta có thể hình dung chức năng này sẽ làm gì và mô tả nó. -Such description is called a *specification* or, in short, a spec, and contains descriptions of use cases together with tests for them, like this: +Mô tả như vậy được gọi là *thông số kỹ thuật* hay nói ngắn gọn là thông số và chứa mô tả về các trường hợp sử dụng cùng với các bài kiểm tra dành cho chúng, như sau: ```js -describe("pow", function() { +describe("luỹ thừa", function() { - it("raises to n-th power", function() { + it("nâng lên mũ n", function() { assert.equal(pow(2, 3), 8); }); }); ``` -A spec has three main building blocks that you can see above: +Một thông số kỹ thuật có ba khối xây dựng chính mà bạn có thể thấy ở trên: `describe("title", function() { ... })` -: What functionality we're describing. In our case we're describing the function `pow`. Used to group "workers" -- the `it` blocks. +: Chúng ta đang mô tả hàm gì. Trong trường hợp của chúng ta, chúng ta đang mô tả hàm `pow`. Được sử dụng để nhóm "công nhân" -- các khối `it`. `it("use case description", function() { ... })` -: In the title of `it` we *in a human-readable way* describe the particular use case, and the second argument is a function that tests it. +: Trong tiêu đề của `it`, chúng ta *theo cách mà con người có thể đọc được* mô tả trường hợp sử dụng cụ thể và đối số thứ hai là một hàm kiểm tra trường hợp đó. `assert.equal(value1, value2)` -: The code inside `it` block, if the implementation is correct, should execute without errors. +: Mã bên trong khối `it`, nếu triển khai đúng, sẽ thực thi mà không có lỗi. - Functions `assert.*` are used to check whether `pow` works as expected. Right here we're using one of them -- `assert.equal`, it compares arguments and yields an error if they are not equal. Here it checks that the result of `pow(2, 3)` equals `8`. There are other types of comparisons and checks, that we'll add later. + Hàm `assert.*` được sử dụng để kiểm tra xem `pow` có hoạt động như mong đợi hay không. Ngay tại đây, chúng ta đang sử dụng một trong số chúng -- `assert.equal`, nó so sánh các đối số và đưa ra lỗi nếu chúng không bằng nhau. Tại đây, nó kiểm tra xem kết quả của `pow(2, 3)` có bằng `8` hay không. Có nhiều loại so sánh và kiểm tra khác mà chúng ta sẽ bổ sung sau. -The specification can be executed, and it will run the test specified in `it` block. We'll see that later. +Thông số kỹ thuật có thể được thực thi và nó sẽ chạy bài kiểm tra được chỉ định trong khối `it`. Chúng ta sẽ thấy điều đó sau. -## The development flow +## Dòng chảy phát triển -The flow of development usually looks like this: +Dòng phát triển thường trông như thế này: -1. An initial spec is written, with tests for the most basic functionality. -2. An initial implementation is created. -3. To check whether it works, we run the testing framework [Mocha](http://mochajs.org/) (more details soon) that runs the spec. While the functionality is not complete, errors are displayed. We make corrections until everything works. -4. Now we have a working initial implementation with tests. -5. We add more use cases to the spec, probably not yet supported by the implementations. Tests start to fail. -6. Go to 3, update the implementation till tests give no errors. -7. Repeat steps 3-6 till the functionality is ready. +1. Thông số kỹ thuật ban đầu được viết, với các bài kiểm tra hàm cơ bản nhất. +2. Triển khai ban đầu được tạo. +3. Để kiểm tra xem nó có hoạt động hay không, chúng ta chạy framework kiểm tra [Mocha](https://mochajs.org/) (sẽ sớm có thêm thông tin chi tiết) để chạy thông số kỹ thuật đó. Trong khi hàm không hoàn thành, lỗi được hiển thị. Chúng ta thực hiện chỉnh sửa cho đến khi mọi thứ hoạt động. +4. Bây giờ chúng ta có một thực hiện ban đầu đang hoạt động với bài kiểm tra. +5. Chúng ta thêm nhiều trường hợp sử dụng hơn vào thông số kỹ thuật, có thể chưa được triển khai hỗ trợ. Các thử nghiệm bắt đầu thất bại. +6. Đến bước 3, cập nhật việc triển khai cho đến khi kiểm tra không có lỗi. +7. Lặp lại các bước 3-6 cho đến khi hàm sẵn sàng. -So, the development is *iterative*. We write the spec, implement it, make sure tests pass, then write more tests, make sure they work etc. At the end we have both a working implementation and tests for it. +Vì vậy, sự phát triển là * lặp đi lặp lại *. Chúng ta viết thông số kỹ thuật, triển khai nó, đảm bảo nó vượt qua các bài kiểm tra, sau đó viết thêm các bài kiểm tra khác, đảm bảo chúng hoạt động, v.v. Cuối cùng, chúng ta vừa có một triển khai hoạt động và các bài kiểm tra cho nó. -Let's see this development flow in our practical case. +Hãy xem dòng phát triển này trong trường hợp thực tế của chúng ta. -The first step is already complete: we have an initial spec for `pow`. Now, before making the implementation, let's use few JavaScript libraries to run the tests, just to see that they are working (they will all fail). +Bước đầu tiên đã hoàn tất: chúng ta có thông số kỹ thuật ban đầu cho `pow`. Bây giờ, trước khi thực hiện, hãy sử dụng một số thư viện JavaScript để chạy bài kiểm tra, chỉ để xem chúng có hoạt động không (tất cả chúng sẽ không thành công). -## The spec in action +## Thông số kỹ thuật hoạt động -Here in the tutorial we'll be using the following JavaScript libraries for tests: +Ở trong hướng dẫn này, chúng ta sẽ sử dụng các thư viện JavaScript sau để kiểm tra: -- [Mocha](http://mochajs.org/) -- the core framework: it provides common testing functions including `describe` and `it` and the main function that runs tests. -- [Chai](http://chaijs.com) -- the library with many assertions. It allows to use a lot of different assertions, for now we need only `assert.equal`. -- [Sinon](http://sinonjs.org/) -- a library to spy over functions, emulate built-in functions and more, we'll need it much later. +- [Mocha](http://mochajs.org/) -- framework cốt lõi: nó cung cấp các hàm kiểm tra phổ biến bao gồm `describe` và `it` và hàm chính chạy các bài kiểm tra. +- [Chai](http://chaijs.com) -- thư viện có nhiều xác nhận. Nó cho phép sử dụng rất nhiều xác nhận khác nhau, bây giờ chúng ta chỉ cần `assert.equal`. +- [Sinon](http://sinonjs.org/) -- một thư viện để theo dõi các hàm, mô phỏng các hàm tích hợp sẵn và hơn thế nữa, chúng ta sẽ cần đến nó sau này. -These libraries are suitable for both in-browser and server-side testing. Here we'll consider the browser variant. +Các thư viện này phù hợp cho cả kiểm tra trên trình duyệt và phía máy chủ. Ở đây chúng ta sẽ xem xét biến thể trình duyệt. -The full HTML page with these frameworks and `pow` spec: +Trang HTML đầy đủ với các khung này và thông số kỹ thuật `pow`: ```html src="index.html" ``` -The page can be divided into five parts: +Trang này có thể được chia thành năm phần: -1. The `
` -- add third-party libraries and styles for tests. -2. The ` - + - + - + - + diff --git a/1-js/03-code-quality/05-testing-mocha/beforeafter.view/test.js b/1-js/03-code-quality/05-testing-mocha/beforeafter.view/test.js index d3de82546..d4df8ad5f 100644 --- a/1-js/03-code-quality/05-testing-mocha/beforeafter.view/test.js +++ b/1-js/03-code-quality/05-testing-mocha/beforeafter.view/test.js @@ -1,16 +1,16 @@ describe("test", function() { - // Mocha usually waits for the tests for 2 seconds before considering them wrong + // Mocha thường đợi các bài kiểm tra trong 2 giây trước khi coi chúng sai - this.timeout(200000); // With this code we increase this - in this case to 200,000 milliseconds + this.timeout(200000); // Với mã này, chúng ta tăng cái này (timeout) - trong trường hợp này là 200.000 mili giây - // This is because of the "alert" function, because if you delay pressing the "OK" button the tests will not pass! + // Điều này là do hàm "alert", bởi vì nếu bạn trì hoãn nhấn nút "OK" thì các bài kiểm tra sẽ không vượt qua! - before(() => alert("Testing started – before all tests")); - after(() => alert("Testing finished – after all tests")); + before(() => alert("Bài kiểm tra bắt đầu – trước tất cả các bài kiểm tra")); + after(() => alert("Bài kiểm tra kết thúc – sau tất cả các bài kiểm tra")); - beforeEach(() => alert("Before a test – enter a test")); - afterEach(() => alert("After a test – exit a test")); + beforeEach(() => alert("Trước một bài kiểm tra – nhập một bài kiểm tra")); + afterEach(() => alert("Trước một bài kiểm tra – nhập một bài kiểm tra")); it('test 1', () => alert(1)); it('test 2', () => alert(2)); diff --git a/1-js/03-code-quality/05-testing-mocha/index.html b/1-js/03-code-quality/05-testing-mocha/index.html index 28a2ea62b..1d3610777 100644 --- a/1-js/03-code-quality/05-testing-mocha/index.html +++ b/1-js/03-code-quality/05-testing-mocha/index.html @@ -1,17 +1,17 @@ - + - + - + @@ -20,17 +20,17 @@ - + - + - + diff --git a/1-js/03-code-quality/05-testing-mocha/pow-1.view/index.html b/1-js/03-code-quality/05-testing-mocha/pow-1.view/index.html index e48a8d3a2..4b549f474 100644 --- a/1-js/03-code-quality/05-testing-mocha/pow-1.view/index.html +++ b/1-js/03-code-quality/05-testing-mocha/pow-1.view/index.html @@ -1,18 +1,18 @@ - + - + - + @@ -21,17 +21,17 @@ - + - + - + diff --git a/1-js/03-code-quality/05-testing-mocha/pow-2.view/index.html b/1-js/03-code-quality/05-testing-mocha/pow-2.view/index.html index e8d6be23d..8ec3889e2 100644 --- a/1-js/03-code-quality/05-testing-mocha/pow-2.view/index.html +++ b/1-js/03-code-quality/05-testing-mocha/pow-2.view/index.html @@ -1,18 +1,18 @@ - + - + - + @@ -21,17 +21,17 @@ - + - + - + diff --git a/1-js/03-code-quality/05-testing-mocha/pow-3.view/index.html b/1-js/03-code-quality/05-testing-mocha/pow-3.view/index.html index c71b0d5d5..5596b92cd 100644 --- a/1-js/03-code-quality/05-testing-mocha/pow-3.view/index.html +++ b/1-js/03-code-quality/05-testing-mocha/pow-3.view/index.html @@ -1,18 +1,18 @@ - + - + - + @@ -31,13 +31,13 @@ } - + - + - + diff --git a/1-js/03-code-quality/05-testing-mocha/pow-4.view/index.html b/1-js/03-code-quality/05-testing-mocha/pow-4.view/index.html index c71b0d5d5..5596b92cd 100644 --- a/1-js/03-code-quality/05-testing-mocha/pow-4.view/index.html +++ b/1-js/03-code-quality/05-testing-mocha/pow-4.view/index.html @@ -1,18 +1,18 @@ - + - + - + @@ -31,13 +31,13 @@ } - + - + - + diff --git a/1-js/03-code-quality/05-testing-mocha/pow-4.view/test.js b/1-js/03-code-quality/05-testing-mocha/pow-4.view/test.js index e5ce2ce43..dc8660071 100644 --- a/1-js/03-code-quality/05-testing-mocha/pow-4.view/test.js +++ b/1-js/03-code-quality/05-testing-mocha/pow-4.view/test.js @@ -15,5 +15,5 @@ describe("pow", function() { }); - // ... more tests to follow here, both describe and it can be added + // ... nhiều bài kiểm tra để theo dõi ở đây, cả describe và it có thể được thêm vào }); diff --git a/1-js/03-code-quality/05-testing-mocha/pow-full.view/index.html b/1-js/03-code-quality/05-testing-mocha/pow-full.view/index.html index 076b1e5a9..43e362214 100644 --- a/1-js/03-code-quality/05-testing-mocha/pow-full.view/index.html +++ b/1-js/03-code-quality/05-testing-mocha/pow-full.view/index.html @@ -1,18 +1,18 @@ - + - + - + @@ -32,13 +32,13 @@ } - + - + - + diff --git a/1-js/03-code-quality/05-testing-mocha/pow-min.view/index.html b/1-js/03-code-quality/05-testing-mocha/pow-min.view/index.html index d82a79dca..d5514e388 100644 --- a/1-js/03-code-quality/05-testing-mocha/pow-min.view/index.html +++ b/1-js/03-code-quality/05-testing-mocha/pow-min.view/index.html @@ -1,18 +1,18 @@ - + - + - + @@ -21,17 +21,17 @@ - + - + - + diff --git a/1-js/03-code-quality/05-testing-mocha/pow-nan.view/index.html b/1-js/03-code-quality/05-testing-mocha/pow-nan.view/index.html index 523ae25ec..ac3b8327a 100644 --- a/1-js/03-code-quality/05-testing-mocha/pow-nan.view/index.html +++ b/1-js/03-code-quality/05-testing-mocha/pow-nan.view/index.html @@ -1,18 +1,18 @@ - + - + - + @@ -29,13 +29,13 @@ } - + - + - +