Tự động hóa
Làm cho thao tác bấm sống được lâu
Bốn thuộc tính để kịch bản nhận ra một cái nút, bốn cách so khớp, nhóm điều kiện VÀ/HOẶC — và vì sao toạ độ luôn là lựa chọn cuối cùng.
7 phút đọc
Đây là câu chuyện hay gặp nhất trong tự động hoá. Bạn dựng một kịch bản, chạy ngon lành, đi ngủ trong tâm trạng phấn khởi. Một tuần sau nó trượt trên nửa số máy, mà kịch bản thì không ai đụng vào.
Gần như luôn luôn, thứ đã đổi là cái màn hình — và thứ bị gãy là cách kịch bản nhận ra cái nút. Cách nhận ra đó gọi là matcher, và chọn nó khéo hay vụng chính là khác biệt giữa một kịch bản sống được một tháng và một kịch bản sống được một ngày.
Matcher thật ra là gì
Mỗi nút bấm, ô nhập, dòng chữ trên máy đều là một element. Matcher mô tả một trong số đó đủ rõ để máy tự tìm lại được nó.
Chính node Bấm (Click) đặt lựa chọn trước mặt bạn trong một câu: "Chọn tọa độ cố định, hoặc để máy tự tìm element rồi bấm vào đó."
Toạ độ là một lời hứa về điểm ảnh. Matcher là một lời mô tả về sự vật. Màn hình thì đổi kích thước; sự vật thì giữ tên của nó.
Cách dựng matcher nhanh nhất là đừng gõ gì cả — UI Inspector viết nó ra từ đúng phần tử bạn click vào.
Bốn thứ bạn có thể mô tả
| Prop | App nói gì về nó |
|---|---|
| resource-id | "Mã định danh do app đặt. Ổn định nhất, có thì ưu tiên dùng." |
| text | Chữ đang hiển thị. Dễ hiểu nhưng đổi theo ngôn ngữ và nội dung. Mặc định so "chứa", không phân biệt hoa thường. |
| content-desc | "Mô tả trợ năng, thường có ở icon không chữ. So như text." |
| class | "Loại widget (Button, EditText…). Nhiều phần tử trùng nhau nên chỉ dùng để thu hẹp thêm." |
resource-id là cái tên chính lập trình viên của app đặt cho cái nút. Người dùng không bao giờ nhìn thấy nó, và đúng vì vậy mà nó sống dai: không ai đi viết lại nó cho một chiến dịch quảng cáo, và nó không bị dịch sang tiếng khác.
text thì ngược lại — dễ đọc nhất và cũng dễ gãy nhất. Trỏ kịch bản vào chữ Sign in là tới ngày cái máy được đặt sang tiếng Việt, nút ghi Đăng nhập, kịch bản đứng hình.
content-desc là cái nhãn mà trình đọc màn hình xướng lên cho người khiếm thị. Những icon không có chữ — trái tim, máy bay giấy, ba chấm — thường có nhãn này, và thường thì đó là chỗ bám duy nhất chúng cho bạn. Một dòng gợi ý khác trong trình soạn thảo nói đúng điều đó từ phía bên kia: "Nhiều app chỉ đặt mô tả (content-description) chứ không có text — chọn “Mô tả” khi text trống."
class đứng một mình thì gần như vô dụng: một màn hình có thể chứa hàng chục cái Button. Nhưng làm điều kiện thứ hai thì rất được việc.
Mục mẹo của Inspector khuyên bám text hoặc content-desc trước, không có mới dùng tới resource-id hay class. Đó là lời khuyên về thứ bạn nhìn thấy được: hai prop đó là hai thứ bạn đọc thẳng trên ảnh chụp và tự mắt mình kiểm được.
Phần mô tả prop lại trả lời một câu hỏi khác — thứ nào ít bị đổi nhất — và câu trả lời ở đó là resource-id.
Cả hai đều có ích. Hãy dựng matcher từ thứ nhìn thấy được, rồi hỏi thêm một câu trước khi đi tiếp: điều kiện này còn đúng không nếu máy được đặt sang ngôn ngữ khác? Nếu không, mà lại có resource-id, thì chuyển sang nó.
Bốn cách so sánh
Chọn xong prop, bạn nói giá trị của nó phải được so với thứ bạn gõ vào theo kiểu nào.
| Phép so sánh | Nó làm gì |
|---|---|
| chứa | "Giá trị prop có chứa chuỗi đã nhập. Chịu được chữ thừa hai bên, nên ưu tiên." |
| bằng | "Giá trị prop phải giống hệt chuỗi đã nhập." |
| bắt đầu bằng | "Giá trị prop mở đầu bằng chuỗi đã nhập. Hợp với text có số đếm phía sau." |
| khớp regex | "So bằng biểu thức chính quy. Chỉ dùng khi ba cách trên không đủ." |
chứa là thứ mà text dùng làm mặc định, và lời khuyên của chính trình soạn thảo là nên ưu tiên nó. App rất hay độn thêm vào nhãn — một dấu cách thừa ở đầu, một huy hiệu nhỏ ở cuối, một ký tự vô hình — và bằng thì trượt với tất cả những thứ đó, còn chứa thì phủi tay đi qua.
bắt đầu bằng đáng đồng tiền với mọi thứ có đếm. Một thẻ hôm nay ghi Tin nhắn (3) mai ghi Tin nhắn (11) vẫn là cái thẻ đó, và Tin nhắn kiểu bắt-đầu-bằng thì tóm được cả hai.
khớp regex là một ngôn ngữ viết mẫu tìm kiếm nâng cao, trong đó vài ký hiệu đại diện cho cả một họ chữ. Mẫu ^Item \d+$ nghĩa là "chữ Item, một dấu cách, rồi một số bất kỳ, và hết". Nó mạnh, mà cũng dễ sai một cách rất kín, nên chính app nói chỉ dùng khi ba cách kia không đủ.
Cả bốn cách đều gắn thêm được hai công tắc: Bỏ qua hoa thường, và phủ định — "Mọi cách so sánh có thể bật Bỏ qua hoa thường và Phủ định (KHÔNG khớp)." Phủ định dành cho những màn hình mà bạn nhận ra nhờ thứ vắng mặt: một dòng không có huy hiệu đã xác minh, một ô không có dòng báo lỗi bên dưới.
Khi nhiều phần tử cùng khớp
Đôi khi nhiều phần tử khớp một cách hoàn toàn chính đáng, mà bạn chỉ muốn một cái. Ô Vị trí (Position) lo việc đó, và dòng gợi ý của nó nói chính xác: "Nếu có nhiều element cùng khớp, chọn cái thứ mấy — đếm từ 0. Bỏ trống là lấy cái đầu tiên."
Đếm từ 0 nghĩa là cái đầu tiên mang số 0, cái thứ hai mang số 1. Tiện cho kiểu "kết quả thứ ba trong danh sách" — nhưng hãy coi nó là phương án muộn, vì cái thứ tự đó là của app, không phải của bạn.
VÀ, HOẶC, và bài toán ngôn ngữ
Một điều kiện thường là đã đủ. Khi không đủ, các điều kiện được xếp vào nhóm:
"Mỗi nhóm gồm nhiều điều kiện. Trong nhóm chọn VÀ (phải đúng hết) hoặc HOẶC (đúng một là được)."
Giữa các nhóm cũng chọn VÀ hoặc HOẶC. Ví dụ: Nhóm 1 text chứa "Đăng nhập" HOẶC Nhóm 2 mô tả chứa "Login" thì bấm được cả hai kiểu app.
Cái ví dụ đó đáng đọc hai lần, vì nó chữa đúng vấn đề mở đầu bài này. VÀ làm hẹp lại: text chứa Tiếp VÀ class là Button, dùng cho màn hình vừa có tiêu đề "Tiếp" vừa có nút "Tiếp". HOẶC làm rộng ra — và làm rộng ra trên hai cái nhãn chính là cách một kịch bản sống sót qua hai ngôn ngữ, hai phiên bản app, hoặc một đợt thử nghiệm A/B mà chẳng ai báo bạn.
Lời khuyên cuối của app về nhóm là lời khuyên tiết chế: "Một điều kiện là đủ trong hầu hết trường hợp. Chỉ thêm nhóm khi màn hình có nhiều phần tử giống nhau." Mỗi điều kiện bạn thêm vào là thêm một thứ có thể thôi đúng.
Thứ tự nên thử
Một resource-id đọc lên nghe như một cái tên. Người dùng làm gì cũng không đổi được nó.
text hoặc content-desc, với phép "chứa". Đọc được, kiểm được ngay trong Inspector, đủ dùng cho hầu hết màn hình.
Hai thứ ghép lại, hoặc một nhóm HOẶC bắc qua cả hai. Dành cho phần tử na ná nhau, và cho app chạy nhiều hơn một ngôn ngữ.
Vị trí, hoặc regex. Khi màn hình thật sự không cho bạn thứ gì khác.
Toạ độ. Cuối cùng. Luôn luôn cuối cùng.
Toạ độ là lựa chọn duy nhất không sống nổi khi bị dời chỗ. Inspector nói thẳng: "Chỉ dùng toạ độ khi không còn cách nào khác, đổi máy hoặc độ phân giải là lệch."
Một toạ độ là lời cá cược rằng cái máy tiếp theo có cùng kích thước màn hình, cùng cỡ chữ hệ thống, và không có thanh thông báo nào chen vào. Đem kịch bản đó chạy hàng loạt thì nó vẫn bấm — chỉ là không phải lúc nào cũng bấm đúng thứ bạn định. Hãy để dành toạ độ cho khung vẽ, bản đồ và game, nơi thật sự chẳng có gì để gọi tên.
Tóm tắt
- Matcher mô tả một phần tử; toạ độ mô tả một điểm ảnh. Hãy ưu tiên lời mô tả.
- resource-id ít đổi nhất, text và content-desc dễ kiểm nhất — dựng bằng thứ nhìn thấy được, rồi hỏi xem nó có sống qua một ngôn ngữ khác không.
- chứa làm mặc định, bắt đầu bằng cho nhãn có số đếm, bằng khi phải khớp tuyệt đối, regex chỉ khi không còn cách đơn giản hơn.
- VÀ làm hẹp, HOẶC làm rộng — một nhóm HOẶC bắc qua hai cái nhãn là cách một kịch bản lo được hai ngôn ngữ.
- Toạ độ để cuối: đổi máy hoặc đổi độ phân giải là lệch.