Tự học Automation Testing Cơ Bản với Selenium - Tại sao không? (Phần I)

Như chúng ta đều biết, Automation Testing (Kiểm thử tự động) đang là xu hướng phát triển ngày nay và chắc chắn ngày càng có nhiều nhu cầu hơn nữa trong tương lai. Tại Việt Nam, các doanh nghiệp hiện tại đang thiếu nguồn lực này vì thế hiểu và áp dụng kiểm thử tự động trong kiểm thử phần mềm sẽ là một điểm cộng đáng kể khi bạn tham gia ứng tuyển vị trí tester ở bất kỳ công ty nào. Với chủ đề hôm nay, mình hi vọng sẽ tập hợp lại những kiến thức đã học trên con đường tìm hiểu Kiểm thử tự động của mình nhằm có thể hỗ trợ phần nào các bạn đang muốn theo con đường này trang bị kiến thức cơ bản về Kiểm thử tự động, có kỹ năng thực hành và xây dựng framework để kiểm thử tự động chức năng của ứng dụng Web với Selenium sử dụng Java.

Giáo trình mà lớp học mình đã và đang theo dựa vào tài liệu này http://www.software-testing-tutorials-automation.com/2014/01/learn-selenium-webdriver-online-free.html . Cụ thể, lộ trình mà mình đã tiếp cận như sau (mình sẽ cập nhật sau này khi viết tiếp những phần khác nếu cần thay đổi gì cho dễ hiểu hơn các bạn nhé):

  • Java Cơ Bản
  • Web Base
  • Selenium + TestNG
  • Thực hành dự án

Trên là cách tiếp cận Kiểm thử tự động mà mình đang theo. Và bây giờ chúng ta hãy cùng nhau bắt đầu nhé!

1. Java Cơ Bản

Như tiêu đề phần này, mục này nhằm trang bị cho chúng ta kiến thức cơ bản về Java trong selenium. Trước khi tìm hiểu về kiểm thử bằng selenium, thì bắt buộc cần phải có kiến thức về Java. Vì thế mục này sẽ giúp chúng ta làm rõ hơn về khái niệm lập trình hướng đối tượng cơ bản nhất mà chúng cần có để sử dụng trong trong các mã kiểm thử bằng selenium webdriver.

Trước khi đi vào những kiến thức cơ bản về Java, bạn cần cài đặt Java:

Tiếp theo, chúng ta cần cài đặt một công cụ để lập trình. Ở đây mình chọn Eclipse vì công cụ này hỗ trợ khá nhiều phần mềm khác để sử dụng khi kiểm thử như TestNG, Cucumber, ....

Sau khi cài đặt xong Java và Eclipse, chúng ta có thể bắt đầu tìm hiểu Java Cơ bản. Ngoài ra, trong lúc lập trình, bạn có thể bỏ túi một số phím tắt sau mà chúng ta có thể dùng khá nhiều:

  • Ctrl+A: Chọn toàn bộ code trong tệp tin hiện tại, và sau đó Ctrl+Shift+F để định dạng lại code trông đẹp và dễ nhìn hơn.
  • Ctrl + space: Không cần phải học thuộc các câu lệnh rồi gõ từng chữ một, như thế sẽ rất mất thời gian. Thay vì đó bạn chỉ cần dùng phím tắt này để xem các gợi ý và chọn đúng câu lệnh bạn cần.
  • sout + space: Lệnh in giá trị ra Console, lệnh này sẽ được dùng thường xuyên để xem code chạy đúng chưa.

Kiểu dữ liệu

Trong Java có 8 kiểu dữ liệu nguyên thủy theo sơ đồ sau:

Cụ thể như sau:

  • Kiểu boolean (logic):
    • Độ dài chỉ có 1 bit, dùng để lưu dữ liệu chỉ có hai trạng thái true hoặc false. Giá trị mặc định là false
    • Ví dụ : boolean isTester = true;
  • Kiểu char:
    • Dùng để lưu dữ liệu kiểu kí tự hoặc số nguyên không âm có kích thước 2 byte (16 bit).
    • Giá trị nhỏ nhất là '\u0000' (hoặc 0). Giá trị lớn nhất là '\uffff' (hoặc 65,535).
    • Ví dụ: char letterC ='C'
  • Kiểu byte:
    • Dùng để lưu dữ liệu kiểu số nguyên có kích thước một byte (8 bit)
    • Giá trị nhỏ nhất là -128 (-2^7). Giá trị lớn nhất là 127. (2^7 -1)
    • Giá trị mặc định là 0.
    • Kiểu dữ liệu byte được sử dụng để lưu giữ khoảng trống trong các mảng lớn, chủ yếu là các số nguyên.
    • Ví dụ: byte b = 200 , byte d = -500
  • Kiểu short:
    • Dùng để lưu dữ liệu có kiểu số nguyên, kích cỡ 2 byte (16 bit).
    • Giá trị nhỏ nhất là -32,768 (-2^15). Giá trị lớn nhất là 32,767. (2^15 -1)
    • Kiểu dữ liệu short cũng có thể được sử dụng để lưu bộ nhớ như kiểu dữ liệu byte.
    • Giá trị mặc định là 0.
    • Ví dụ: short c = 10000, short s = -20000
  • Kiểu int:
    • Dùng để lưu dữ liệu có kiểu số nguyên, kích cỡ 4 byte (32 bit).
    • Giá trị nhỏ nhất là - 2,147,483,648.(-2^31). Giá trị lớn nhất là 2,147,483,647. (2^31 -1)
    • Được sử dụng như là kiểu dữ liệu mặc định cho các giá trị nguyên.
    • Giá trị mặc định là 0.
    • Ví dụ: int i = 100000, int j = -200000
  • Kiểu long:
    • Dùng để lưu dữ liệu có kiểu số nguyên có kích thước lên đến 8 byte.
    • Giá trị nhỏ nhất là -9,223,372,036,854,775,808.(-2^63). Giá trị lớn nhất là 9,223,372,036,854,775,807. (2^63 -1)
    • Kiểu này được sử dụng khi cần một dải giá trị rộng hơn int.
    • Giá trị mặc định là 0L.
    • Ví dụ: long a = 100000L, int b = -200000L
  • Kiểu float:
    • Dùng để lưu dữ liệu có kiểu số thực, kích cỡ 4 byte (32 bit)
    • Được sử dụng chủ yếu để lưu bộ nhớ trong các mảng rộng hơn các số dấu chấm động.
    • Không bao giờ được sử dụng cho các giá trị chính xác như currency.
    • Giá trị mặc định là 0.0f.
    • Ví dụ: float f1 = 234.5f
  • Kiểu double:
    • Kiểu dữ liệu double được sử dụng để lưu dữ liệu có kiểu số thực có kích thước lên đến 8 byte
    • Kiểu dữ liệu này được sử dụng như là kiểu mặc định cho các giá trị decimal.
    • Giống như kiểu float, kiểu này không bao giờ được sử dụng cho các giá trị chính xác như currency.
    • Giá trị mặc định là 0.0d.
    • Ví dụ: double d1 = 123.4

String Class

Trong Java việc thao tác với kiểu String (kiểu chuỗi) là rất nhiều, vì vậy việc tìm hiểu và nắm vững các kiến thức về các chức năng mà lớp String cung cấp là điều vô cùng cần thiết. Vậy chúng ta hãy bắt đầu với từng chức năng trong lớp String:

  • So sánh 2 chuỗi: Để so sánh 2 chuỗi, chúng ta cần dùng cú pháp: st1.equals(st2). Nó sẽ trả về true nếu 2 chuỗi này giống nhau, ngược lại thì sẽ trả về false. Ví dụ:
st1 = "java"; 
st2 = "tester"; 
boolean compareEqual = st1.equals(st2); // compareEqual có giá trị là false
  • Nối 2 chuỗi: Để nối chuỗi 1 vào chuỗi 2, chúng ta dùng cú pháp: st1.concat(st2). Ví dụ:
st1 = "java";
st2 = "tester";
String st3 = st1.concat(st2);//st3 có giá trị là javatester
  • Tìm ký tự tại vị trí thứ n trong chuỗi, ta dùng cú pháp: st1.charAt(n). với 0 là vị trí đầu tiên Ví dụ:
st1 = "java"
st1.charAt(2); //trả ra ký tự 
  • Tìm độ dài của 1 chuỗi, cú pháp: st1.length() Ví dụ:
st1 = "java";
st1.length(); // kết quả là 4
  • Chuyển đổi chuỗi sang kiểu in hoa, cú pháp: st1.toUpperCase() Ví dụ:
st1 = "java";
st1.toUpperCase(); // kết quả là JAVA
  • Chuyển đổi chuỗi sang kiểu thường, cú pháp: st1.toLowerCase() Ví dụ:
st1 = "Java";
st1.toLowerCase(); // kết quả là java
  • Tìm vị trí đầu tiên của ký tự trong chuỗi, không tìm thấy trả kết quả -1 Ví dụ:
st1 = "java for tester";
st1.indexOf("a");// kết quả là 1  
st1.indexOf("ba");// kết quả là -1
  • Tìm vị trí trong chuỗi bắt đầu từ vị trí thứ n, không tìm thấy kết quả trả ra -1 Ví dụ:
st1 = "java for tester";
st1.indexOf("a",2); //kết quả là 3
st1.indexOf("a",4); //kết quả là -1
  • Chuyển đổi từ kiểu số sang kiểu chuỗi. Ví dụ:
int i = 90;
String st1 = String.valueOf(i); //st1có giá trị là chuỗi "90"
  • Chuyển đổi từ kiểu chuỗi sang kiểu số: Ví dụ:
String st1 = "40";
int i = Integer.parseInt(st1); // i = 40
  • Cắt chuỗi: Ví dụ:
String st1 = "java for tester";
st1.subString(0,4);// trả về chuỗi từ vị trí 0 (vị trí đầu tiên) đến vị trí thứ 4, Kết quả là java
  • Tách chuỗi: Ví dụ:
String sp[] = st1.split(" ");// st1 được cắt theo chuỗi " ", nên mảng sp sẽ có 3 phần tử là java, for và tester
  • Trim chuỗi: Nếu trong chuỗi có bắt đầu hoặc kết thúc bằng ký tự trống " " thì khi dùng hàm này sẽ được bỏ đi phần ký tự trống ở đầu và đuôi của chuỗi. Ví dụ:
st1 = " java for tester ";
st1.trim();// kết quả là "java for tester"

Khối lệnh điều kiện If ... Else

Khi bạn muốn thực hiện một đoạn mã nếu nó thỏa mãn một điều kiện gì đó thì câu lệnh điều kiện if... else rất hữu ích trong trường hợp này. Chúng ta sẽ phân tích từng trường hợp của khối điều kiện này.

  • Cấu trúc if khuyết else: Cú pháp:
>         if (điều kiện 1) {
>             // hành động 1
>         }
>             // Lệnh kế tiếp

Giải thích: nếu điều kiện 1 trả về kết quả là true ( nghĩa là điều kiện 1 đúng) thì hành động 1 được thực hiện. Ngược lại nếu điều kiện 1 là sai (kết quả trả về false) thì hành động 1 không được thực hiện. Ví dụ:

if (2 > 1)  {
                System.out.println("hello tester");
            }
        // khi chạy chương trình sẽ in ra màn hình dòng chữ hello tester vì điều kiện 2 > 1 là đúng
  • Cấu trúc if... else đầy đủ. Cú pháp:
>          if (điều kiên 1) {
>             // hành động 1
>         } else {
>             // hành động 2
>         }
>             // Lệnh kế tiếp

Giải thích: nếu điều kiện 1 là đúng thì hành động 1 được thực hiện, ngược lại nếu điều kiện 1 là sai thì hành động 2 sẽ được thực hiện Ví dụ:

if (1 > 2) {
             System.out.println("bye");
         } else {
             System.out.println("hello");
         }
     // Khi chạy chương trình dòng hello sẽ được in ra vì điều kiện 1> 2 là sai.
  • Cấu trúc điều khiển if - else if - else. Cú pháp:
>         if (điều kiên 1) {
>             // hành động 1
>         } else if (điều kiện 2) {
>             // hành động 2
>         } else if (điều kiện 3) {
>             // hành động 3
>         } else {
>             // hành động 4
>         }
>         // Lệnh kế tiếp

Giải thích: - Với cấu trúc này thì trình biên dịch sẽ kiểm tra, nếu điều kiện 1 là đúng thì hành đồng 1 được thực hiện sau đó thực hiện lệnh kế tiếp. - Nếu điều kiện 1 là sai thì sẽ kiểm tra tiếp điều kiện 2, nếu điều kiện 2 đúng thì thực hiện hành động 2, sau đó thực hiện lệnh kế tiếp. - Nếu điều kiện 2 là sai thì sẽ kiểm tra điều kiện 3, nếu điều kiện 3 là đúng thì thực hiện hành động 3, sau đó thực hiện lệnh kế tiếp. - Nếu điều kiện 3 là sai thì thực hiện thành động 4, sau đó thực hiện lệnh kế tiếp.

Vòng lặp For

  • Cú pháp:
>         for ([biểu_thức_1]; [biểu_thức_2]; [biểu_thức_3]) {
>             // Các lệnh
>         }
>         // Lệnh kế tiếp
  • Giải thích:
    • biểu_thức_1: là biểu thức tính ra giá trị khởi đầu cho biến của for.
    • biểu_thức_2: là biểu thức tính ra giá trị điều kiện lặp của for.
    • biểu_thức_3: là bước nhảy của biến sau mỗi lần lặp.
    • Lưu ý: Các biểu thức có thể vắng mặt trong cấu trúc của vòng lặp for nhưng các dấu chấm phẩy vẫn phải có. Mỗi biểu thức trong cấu trúc for có thể là một hoặc nhiều biểu thức đơn. Nếu trong trường hợp một biểu thức có nhiều biểu thức đơn thì các biểu thức đơn được viết cách nhau bởi dấu phẩy (,) và các biểu thức đơn đó được thực hiện từ trái qua phải.
    • Quy trình hoạt động của vòng lặp for trải qua các bước sau:
      • Bước 1: Các lệnh ở biểu_thức_1 được thực hiện trước tiên. Trong biểu thức này có thể có nhiều biểu thức đơn và viết ngăn cách nhau bởi dấu phẩy.
      • Bước 2: Kiểm tra giá trị của biểu_thức_2 (điều kiện lặp). Nếu biểu thức này có giá trị đúng (true) thì chuyển sang Bước 3, ngược lại thì chuyển đến Bước 6.
      • Bước 3: Lần lượt thực hiện các lệnh trong thân vòng lặp.
      • Bước 4: Thực hiện các lệnh trong biểu_thức_3. Trong biểu thức này có thể có nhiều biểu thức đơn và viết ngăn cách nhau bởi dấu phẩy.
      • Bước 5: Quay lại Bước 2.
      • Bước 6: Thực hiện các lệnh bên ngoài vòng lặp for.
  • Ví dụ: in ra màn hình 5 số nguyên đầu tiên
for (int i = 1; i <= 5; i++) {
        System.out.println(i);  
    }
    // Khi chạy chương trình vào vòng lặp for, sẽ khởi tạo biến i có giá trị =1, sau đó kiểm tra i <=5 là đúng thì thực hiện in 1 ra màn hình. Sau đó tăng i lên 1 là thành 2; tiếp tục kiểm tra i <=5 (2<=5) là đúng in 2 ra màn hình... tiếp tục như vậy cho đến khi i=5 kiểm tra i<=5 (5<=5) là đúng, in 5 ra màn hình và tăng i lên 1 là 6 và kiểm tra i<=5 (6<=5) là sai liền thoát khỏi vòng lặp.

Vòng lặp while

Vòng lặp while là cấu trúc điều khiển lặp được dùng để thực hiện một lệnh hay một khối lệnh với số lần lặp chưa xác định trước. Với cấu trúc này điều kiện lặp được kiểm tra trước khi thực hiện thân của vòng lặp.

  • Cú pháp:
>     while (điều_kiện_lặp) {
>         // Các lệnh
>     }
>     // Lệnh kế tiếp
  • Giải thích: - điều_kiện_lặp là biểu thức để xác định điều kiện lặp. Biểu thức này phải trả về giá trị là true hoặc false. - Các lệnh nằm trong cặp dấu {} là thân của vòng lặp. - Cách hoạt động: - Đầu tiên, vòng lặp while sẽ tính giá trị của biểu thức điều_kiện_lặp. Khi biểu thức này có giá trị đúng (true) thì những lệnh nằm trong thân của vòng lặp sẽ được thực hiện; sau khi thực hiện xong các lệnh này thì biểu thức điều_kiện_lặp được kiểm tra lại để quyết định có lặp tiếp hay không. - Như vậy, những lệnh nằm trong thân vòng lặp sẽ lần lượt được làm đi làm lại nhiều lần trong khi biểu thức điều_kiện_lặp còn có giá trị đúng. Nếu đến một lúc nào đó biểu thức điều_kiện_lặp có giá trị sai (false) thì các lệnh trong thân vòng lặp sẽ không được thực hiện và vòng lặp while sẽ kết thúc. - Lưu ý: Vòng lặp while kiểm tra điều kiện trước rồi mới thực hiện các câu lệnh trong thân vòng lặp nên nếu ngay từ đầu biểu thức điều_kiện_lặp đã có giá trị sai thì vòng lặp while sẽ không được thực hiện bất cứ lần nào. Trong thân của vòng lặp while phải có lệnh làm thay đổi giá trị của biểu thức điều_kiện_lặp để đảm bảo sau một số lần thực hiện thì biểu thức điều kiện sẽ có giá trị sai và kết thúc vòng lặp. Nếu trong trường hợp thân của vòng lặp không có lệnh làm thay đổi giá trị của biểu thức thì phải sử dụng từ khóa break để thoát khỏi vòng lặp.
  • Ví dụ:
	     int i =0;
	     while (i < 10) {
             System.out.println(i);
	         i ++; 
	     }
// Chương trình này sẽ in ra màn hình từ 0 đến 9

Vòng lặp do... while

Vòng lặp do - while là cấu trúc điều khiển lặp được dùng để thực hiện một lệnh hay một khối lệnh với số lần lặp chưa xác định trước nhưng khác với while, cấu trúc do - while chỉ kiểm tra điều kiện lặp sau khi thân vòng lặp đã được thực hiện một lần.

  • Cú pháp:
>         do {
>             // Các lệnh
>         } while (điều_kiện_lặp);
>        // Lệnh kế tiếp
>        
  • Giải thích:
    • điều_kiện_lặp là biểu thức để xác định điều kiện lặp. Biểu thức này phải trả về giá trị là đúng (true) hoặc sai (false).
    • Các lệnh nằm trong cặp dấu {} là thân của vòng lặp.
    • Cách hoạt động:
      • Đầu tiên, các lệnh nằm trong thân của vòng lặp do - while sẽ được thực hiện. Sau khi thực hiện xong các lệnh này thì biểu thức điều_kiện_lặp sẽ được kiểm tra: nếu biểu thức này có giá trị đúng (true) thì tiếp tục quay lại thực hiện các lệnh trong thân vòng lặp. Nếu đến một lúc nào đó biểu thức điều_kiện_lặp có giá trị sai (false) thì các lệnh trong thân vòng lặp sẽ không được thực hiện và vòng lặp do - while sẽ kết thúc.
      • Lưu ý: Vòng lặp do - while thực hiện các câu lệnh trong thân vòng lặp trước rồi mới kiểm tra điều kiện nên các câu lệnh nằm trong thân vòng lặp sẽ được thực hiện ít nhất là một lần. Sau đó, tùy theo kết quả của biểu thức điều kiện, chương trình sẽ tiếp tục thực hiện hoặc thoát ra khỏi vòng lặp và thực hiện các lệnh nằm ngoài vòng lặp. Nó hoàn toàn ngược với vòng lặp while: vòng lặp while kiểm tra trước rồi mới thực hiện, còn do - while thực hiện trước rồi mới kiểm tra (trong một số trường hợp thì kết quả của 2 vòng lặp này là giống nhau nên các bạn cố gắng nắm chắc 2 loại vòng lặp này để lựa chọn loại vòng lặp phù hợp với yêu cầu của chương trình).
  • Ví dụ:
      	     int i =0;
	     do {
	    	System.out.println(i);
			i ++;
         } while (i <10);
// Chương trình này sẽ in ra màn hình từ 0 đến 9

THAM KHẢO: