Khả năng thử nghiệm thực tế của Robot Framework được cung cấp bởi các thư viện thử nghiệm. Có rất nhiều thư viện hiện có, một số thư viện thậm chí còn đi kèm với khung cốt lõi, nhưng vẫn thường có nhu cầu tạo thư viện mới. Nhiệm vụ này không quá phức tạp vì như chương này minh họa, API thư viện của Robot Framework rất đơn giản và dễ hiểu
API động theo hầu hết các cách tương tự như API tĩnh. Ví dụ: báo cáo trạng thái từ khóa, ghi nhật ký và trả về giá trị hoạt động chính xác theo cùng một cách. Quan trọng nhất, không có sự khác biệt trong việc nhập các thư viện động và sử dụng từ khóa của chúng so với các thư viện khác. Nói cách khác, người dùng không cần biết thư viện của họ sử dụng API nào
Sự khác biệt duy nhất giữa thư viện tĩnh và thư viện động là cách Robot Framework phát hiện thư viện triển khai những từ khóa nào, những đối số và tài liệu nào mà các từ khóa này có và cách các từ khóa thực sự được thực thi. Với API tĩnh, tất cả điều này được thực hiện bằng phản chiếu, nhưng các thư viện động có các phương thức đặc biệt được sử dụng cho các mục đích này
Một trong những lợi ích của API động là bạn có thể linh hoạt hơn trong việc tổ chức thư viện của mình. Với API tĩnh, bạn phải có tất cả các từ khóa trong một lớp hoặc mô-đun, trong khi với API động, chẳng hạn, bạn có thể triển khai từng từ khóa dưới dạng một lớp riêng biệt. Tuy nhiên, trường hợp sử dụng này không quá quan trọng với Python vì khả năng động và tính đa kế thừa của nó đã mang lại nhiều tính linh hoạt và cũng có khả năng sử dụng
Một trường hợp sử dụng chính khác cho API động là triển khai một thư viện để nó hoạt động như một proxy cho một thư viện thực tế có thể chạy trên một số quy trình khác hoặc thậm chí trên một máy khác. Loại thư viện proxy này có thể rất mỏng và vì tên từ khóa và tất cả thông tin khác được lấy động nên không cần cập nhật proxy khi từ khóa mới được thêm vào thư viện thực tế
Phần này giải thích cách API động hoạt động giữa Robot Framework và các thư viện động. Việc các thư viện này thực sự được triển khai như thế nào không quan trọng đối với Robot Framework [ví dụ: cách gọi phương thức run_keyword
được ánh xạ tới việc triển khai từ khóa chính xác] và có thể thực hiện nhiều cách tiếp cận khác nhau. Người dùng Python cũng có thể thấy dự án PythonLibCore hữu ích
Các thư viện động cho biết chúng triển khai những từ khóa nào bằng phương thức get_keyword_names
. Phương thức này không thể nhận bất kỳ đối số nào và nó phải trả về một danh sách hoặc mảng các chuỗi chứa tên của các từ khóa mà thư viện triển khai
Nếu tên từ khóa được trả về chứa nhiều từ, chúng có thể được trả về cách nhau bằng dấu cách hoặc dấu gạch dưới hoặc ở định dạng camelCase. Ví dụ: ['first keyword', 'second keyword']
, ['first_keyword', 'second_keyword']
và ['firstKeyword', 'secondKeyword']
đều sẽ được ánh xạ tới các từ khóa Từ khóa đầu tiên và Từ khóa thứ hai
Thư viện động phải luôn có phương thức này. Nếu nó bị thiếu hoặc nếu gọi nó không thành công vì một số lý do, thư viện được coi là thư viện tĩnh
Các phương pháp đánh dấu để hiển thị dưới dạng từ khóa
Nếu một thư viện động nên chứa cả hai phương thức có nghĩa là từ khóa và phương thức có nghĩa là phương thức trợ giúp riêng, có thể là khôn ngoan khi đánh dấu các phương thức từ khóa như vậy để dễ triển khai hơn get_keyword_names
. Trình trang trí
class DynamicExample: def get_keyword_names[self]: return ['first keyword', 'second keyword'] def run_keyword[self, name, args, kwargs]: print["Running keyword '%s' with positional arguments %s and named arguments %s." % [name, args, kwargs]]1 cho phép thực hiện điều này một cách dễ dàng vì nó tạo ra một phương thức được trang trí. Điều này cho phép tạo danh sách từ khóa chỉ bằng cách kiểm tra thuộc tính
class DynamicExample: def get_keyword_names[self]: return ['first keyword', 'second keyword'] def run_keyword[self, name, args, kwargs]: print["Running keyword '%s' with positional arguments %s and named arguments %s." % [name, args, kwargs]]2 trên mọi phương thức trong thư viện trong thời gian
get_keyword_names
from robot.api.deco import keyword class DynamicExample: def get_keyword_names[self]: # Get all attributes and their values from the library. attributes = [[name, getattr[self, name]] for name in dir[self]] # Filter out attributes that do not have 'robot_name' set. keywords = [[name, value] for name, value in attributes if hasattr[value, 'robot_name']] # Return value of 'robot_name', if given, or the original 'name'. return [value.robot_name or name for name, value in keywords] def helper_method[self]: # ... @keyword def keyword_method[self]: # ...
Các thư viện động có một phương pháp đặc biệt run_keyword
[bí danh
class DynamicExample: def get_keyword_names[self]: return ['first keyword', 'second keyword'] def run_keyword[self, name, args, kwargs]: print["Running keyword '%s' with positional arguments %s and named arguments %s." % [name, args, kwargs]]5] để thực hiện các từ khóa của họ. Khi một từ khóa từ thư viện động được sử dụng trong dữ liệu thử nghiệm, Robot Framework sử dụng phương thức
run_keyword
để thực thi từ khóa đó. Phương thức này có hai hoặc ba đối số. Đối số đầu tiên là một chuỗi chứa tên của từ khóa sẽ được thực thi theo cùng định dạng như được trả về bởi get_keyword_names
. Đối số thứ hai là danh sách được cung cấp cho từ khóa trong dữ liệu thử nghiệm và đối số thứ ba tùy chọn là một từ điển chứa. Nếu đối số thứ ba bị thiếu và không được hỗ trợ và các đối số có tên khác được ánh xạ tới các đối số vị tríGhi chú
Trước Robot Framework 3. 1, các đối số được đặt tên bình thường được ánh xạ tới các đối số vị trí bất kể run_keyword
có chấp nhận hai hoặc ba đối số hay không. Đối số thứ ba chỉ có thể có các đối số được đặt tên miễn phí
Sau khi nhận được tên từ khóa và các đối số, thư viện có thể thực thi từ khóa một cách tự do, nhưng nó phải sử dụng cùng một cơ chế để giao tiếp với khung như các thư viện tĩnh. Điều này có nghĩa là sử dụng các ngoại lệ để báo cáo trạng thái từ khóa, ghi nhật ký bằng cách ghi vào đầu ra tiêu chuẩn hoặc bằng cách sử dụng API ghi nhật ký được cung cấp và sử dụng câu lệnh trả về trong run_keyword
để trả lại thứ gì đó
Mỗi thư viện động phải có cả phương thức get_keyword_names
và run_keyword
nhưng các phương thức còn lại trong API động là tùy chọn. Ví dụ dưới đây cho thấy một thư viện động, mặc dù tầm thường, đang hoạt động
class DynamicExample: def get_keyword_names[self]: return ['first keyword', 'second keyword'] def run_keyword[self, name, args, kwargs]: print["Running keyword '%s' with positional arguments %s and named arguments %s." % [name, args, kwargs]]
Nếu một thư viện động chỉ triển khai các phương thức get_keyword_names
và run_keyword
, Robot Framework không có bất kỳ thông tin nào về các đối số mà các từ khóa đã triển khai chấp nhận. Ví dụ: cả Từ khóa thứ nhất và Từ khóa thứ hai trong ví dụ trên đều có thể được sử dụng với bất kỳ đối số nào. Điều này có vấn đề, bởi vì hầu hết các từ khóa thực đều mong đợi một số lượng từ khóa nhất định và trong những trường hợp này, chúng sẽ cần tự kiểm tra số lượng đối số
Các thư viện động có thể truyền đạt những đối số mà từ khóa của họ mong đợi bằng cách sử dụng phương pháp
*** Test Cases *** # args # args, kwargs Positional only Dynamic x # [x] # [x], {} Dynamic x y # [x, y] # [x, y], {} Dynamic x y z # [x, y, z] # [x, y, z], {} Named only Dynamic a=x # [x] # [], {a: x} Dynamic c=z a=x b=y # [x, y, z] # [], {a: x, b: y, c: z} Positional and named Dynamic x b=y # [x, y] # [x], {b: y} Dynamic x y c=z # [x, y, z] # [x, y], {c: z} Dynamic x b=y c=z # [x, y, z] # [x], {y: b, c: z} Intermediate missing Dynamic x c=z # [x, d1, z] # [x], {c: z}4 [bí danh
*** Test Cases *** # args # args, kwargs Positional only Dynamic x # [x] # [x], {} Dynamic x y # [x, y] # [x, y], {} Dynamic x y z # [x, y, z] # [x, y, z], {} Named only Dynamic a=x # [x] # [], {a: x} Dynamic c=z a=x b=y # [x, y, z] # [], {a: x, b: y, c: z} Positional and named Dynamic x b=y # [x, y] # [x], {b: y} Dynamic x y c=z # [x, y, z] # [x, y], {c: z} Dynamic x b=y c=z # [x, y, z] # [x], {y: b, c: z} Intermediate missing Dynamic x c=z # [x, d1, z] # [x], {c: z}5]. Phương thức này lấy tên của một từ khóa làm đối số và nó phải trả về một danh sách các chuỗi chứa các đối số được chấp nhận bởi từ khóa đó
Tương tự như các từ khóa khác, từ khóa động có thể yêu cầu bất kỳ số lượng , có , chấp nhận , chấp nhận và có. Cú pháp cách biểu diễn tất cả các biến khác nhau này bắt nguồn từ cách chúng được chỉ định trong Python và được giải thích trong bảng sau
Biểu diễn các đối số khác nhau bằng*** Test Cases *** # args # args, kwargs Positional only Dynamic x # [x] # [x], {} Dynamic x y # [x, y] # [x, y], {} Dynamic x y z # [x, y, z] # [x, y, z], {} Named only Dynamic a=x # [x] # [], {a: x} Dynamic c=z a=x b=y # [x, y, z] # [], {a: x, b: y, c: z} Positional and named Dynamic x b=y # [x, y] # [x], {b: y} Dynamic x y c=z # [x, y, z] # [x, y], {c: z} Dynamic x b=y c=z # [x, y, z] # [x], {y: b, c: z} Intermediate missing Dynamic x c=z # [x, d1, z] # [x], {c: z}4 Loại đối số Cách biểu diễnVí dụKhông có đối sốDanh sách trống.
*** Test Cases *** # args # args, kwargs Positional only Dynamic x # [x] # [x], {} Dynamic x y # [x, y] # [x, y], {} Dynamic x y z # [x, y, z] # [x, y, z], {} Named only Dynamic a=x # [x] # [], {a: x} Dynamic c=z a=x b=y # [x, y, z] # [], {a: x, b: y, c: z} Positional and named Dynamic x b=y # [x, y] # [x], {b: y} Dynamic x y c=z # [x, y, z] # [x, y], {c: z} Dynamic x b=y c=z # [x, y, z] # [x], {y: b, c: z} Intermediate missing Dynamic x c=z # [x, d1, z] # [x], {c: z}7Một hoặc nhiều Danh sách các chuỗi chứa tên đối số.
*** Test Cases *** # args # args, kwargs Positional only Dynamic x # [x] # [x], {} Dynamic x y # [x, y] # [x, y], {} Dynamic x y z # [x, y, z] # [x, y, z], {} Named only Dynamic a=x # [x] # [], {a: x} Dynamic c=z a=x b=y # [x, y, z] # [], {a: x, b: y, c: z} Positional and named Dynamic x b=y # [x, y] # [x], {b: y} Dynamic x y c=z # [x, y, z] # [x, y], {c: z} Dynamic x b=y c=z # [x, y, z] # [x], {y: b, c: z} Intermediate missing Dynamic x c=z # [x, d1, z] # [x], {c: z}8,
*** Test Cases *** # args # args, kwargs Positional only Dynamic x # [x] # [x], {} Dynamic x y # [x, y] # [x, y], {} Dynamic x y z # [x, y, z] # [x, y, z], {} Named only Dynamic a=x # [x] # [], {a: x} Dynamic c=z a=x b=y # [x, y, z] # [], {a: x, b: y, c: z} Positional and named Dynamic x b=y # [x, y] # [x], {b: y} Dynamic x y c=z # [x, y, z] # [x, y], {c: z} Dynamic x b=y c=z # [x, y, z] # [x], {y: b, c: z} Intermediate missing Dynamic x c=z # [x, d1, z] # [x], {c: z}9
Hai cách để biểu thị tên đối số và giá trị mặc định
- Là một chuỗi trong đó tên và mặc định được phân tách bằng
*** Test Cases *** # args, kwargs No arguments Dynamic # [], {} Positional only Dynamic x # [x], {} Dynamic x y # [x, y], {} Free named only Dynamic x=1 # [], {x: 1} Dynamic x=1 y=2 z=3 # [], {x: 1, y: 2, z: 3} Free named with positional Dynamic x y=2 # [x], {y: 2} Dynamic x y=2 z=3 # [x], {y: 2, z: 3} Free named with normal named Dynamic a=1 x=1 # [], {a: 1, x: 1} Dynamic b=2 x=1 a=1 # [], {a: 1, b: 2, x: 1}
0 - Là một bộ có tên và mặc định là các mục riêng biệt. Mới trong Robot Framework 3. 2
*** Test Cases *** # args, kwargs No arguments Dynamic # [], {} Positional only Dynamic x # [x], {} Dynamic x y # [x, y], {} Free named only Dynamic x=1 # [], {x: 1} Dynamic x=1 y=2 z=3 # [], {x: 1, y: 2, z: 3} Free named with positional Dynamic x y=2 # [x], {y: 2} Dynamic x y=2 z=3 # [x], {y: 2, z: 3} Free named with normal named Dynamic a=1 x=1 # [], {a: 1, x: 1} Dynamic b=2 x=1 a=1 # [], {a: 1, b: 2, x: 1}1,
*** Test Cases *** # args, kwargs No arguments Dynamic # [], {} Positional only Dynamic x # [x], {} Dynamic x y # [x, y], {} Free named only Dynamic x=1 # [], {x: 1} Dynamic x=1 y=2 z=3 # [], {x: 1, y: 2, z: 3} Free named with positional Dynamic x y=2 # [x], {y: 2} Dynamic x y=2 z=3 # [x], {y: 2, z: 3} Free named with normal named Dynamic a=1 x=1 # [], {a: 1, x: 1} Dynamic b=2 x=1 a=1 # [], {a: 1, b: 2, x: 1}2
*** Test Cases *** # args, kwargs No arguments Dynamic # [], {} Positional only Dynamic x # [x], {} Dynamic x y # [x, y], {} Free named only Dynamic x=1 # [], {x: 1} Dynamic x=1 y=2 z=3 # [], {x: 1, y: 2, z: 3} Free named with positional Dynamic x y=2 # [x], {y: 2} Dynamic x y=2 z=3 # [x], {y: 2, z: 3} Free named with normal named Dynamic a=1 x=1 # [], {a: 1, x: 1} Dynamic b=2 x=1 a=1 # [], {a: 1, b: 2, x: 1}3,
*** Test Cases *** # args, kwargs No arguments Dynamic # [], {} Positional only Dynamic x # [x], {} Dynamic x y # [x, y], {} Free named only Dynamic x=1 # [], {x: 1} Dynamic x=1 y=2 z=3 # [], {x: 1, y: 2, z: 3} Free named with positional Dynamic x y=2 # [x], {y: 2} Dynamic x y=2 z=3 # [x], {y: 2, z: 3} Free named with normal named Dynamic a=1 x=1 # [], {a: 1, x: 1} Dynamic b=2 x=1 a=1 # [], {a: 1, b: 2, x: 1}4[varargs] Đối số sau các đối số vị trí có thể có và các giá trị mặc định của chúng có tiền tố
*** Test Cases *** # args, kwargs No arguments Dynamic # [], {} Positional only Dynamic x # [x], {} Dynamic x y # [x, y], {} Free named only Dynamic x=1 # [], {x: 1} Dynamic x=1 y=2 z=3 # [], {x: 1, y: 2, z: 3} Free named with positional Dynamic x y=2 # [x], {y: 2} Dynamic x y=2 z=3 # [x], {y: 2, z: 3} Free named with normal named Dynamic a=1 x=1 # [], {a: 1, x: 1} Dynamic b=2 x=1 a=1 # [], {a: 1, b: 2, x: 1}5.
*** Test Cases *** # args, kwargs No arguments Dynamic # [], {} Positional only Dynamic x # [x], {} Dynamic x y # [x, y], {} Free named only Dynamic x=1 # [], {x: 1} Dynamic x=1 y=2 z=3 # [], {x: 1, y: 2, z: 3} Free named with positional Dynamic x y=2 # [x], {y: 2} Dynamic x y=2 z=3 # [x], {y: 2, z: 3} Free named with normal named Dynamic a=1 x=1 # [], {a: 1, x: 1} Dynamic b=2 x=1 a=1 # [], {a: 1, b: 2, x: 1}6,
*** Test Cases *** # args, kwargs No arguments Dynamic # [], {} Positional only Dynamic x # [x], {} Dynamic x y # [x, y], {} Free named only Dynamic x=1 # [], {x: 1} Dynamic x=1 y=2 z=3 # [], {x: 1, y: 2, z: 3} Free named with positional Dynamic x y=2 # [x], {y: 2} Dynamic x y=2 z=3 # [x], {y: 2, z: 3} Free named with normal named Dynamic a=1 x=1 # [], {a: 1, x: 1} Dynamic b=2 x=1 a=1 # [], {a: 1, b: 2, x: 1}7,
*** Test Cases *** # args, kwargs No arguments Dynamic # [], {} Positional only Dynamic x # [x], {} Dynamic x y # [x, y], {} Free named only Dynamic x=1 # [], {x: 1} Dynamic x=1 y=2 z=3 # [], {x: 1, y: 2, z: 3} Free named with positional Dynamic x y=2 # [x], {y: 2} Dynamic x y=2 z=3 # [x], {y: 2, z: 3} Free named with normal named Dynamic a=1 x=1 # [], {a: 1, x: 1} Dynamic b=2 x=1 a=1 # [], {a: 1, b: 2, x: 1}8 [kwargs]Đối số cuối cùng có tiền tố
*** Test Cases *** # args, kwargs No arguments Dynamic # [], {} Positional only Dynamic x # [x], {} Dynamic x y # [x, y], {} Free named only Dynamic x=1 # [], {x: 1} Dynamic x=1 y=2 z=3 # [], {x: 1, y: 2, z: 3} Free named with positional Dynamic x y=2 # [x], {y: 2} Dynamic x y=2 z=3 # [x], {y: 2, z: 3} Free named with normal named Dynamic a=1 x=1 # [], {a: 1, x: 1} Dynamic b=2 x=1 a=1 # [], {a: 1, b: 2, x: 1}9. Yêu cầu
run_keyword
để. *** Test Cases *** # args, kwargs Named-only only Dynamic named=value # [], {named: value} Dynamic named=value named2=2 # [], {named: value, named2: 2} Named-only with positional and varargs Dynamic argument named=xxx # [argument], {named: xxx} Dynamic a1 a2 named=3 # [a1, a2], {named: 3} Named-only with normal named Dynamic named=foo positional=bar # [], {positional: bar, named: foo} Named-only with free named Dynamic named=value foo=bar # [], {named: value, foo=bar} Dynamic named2=2 third=3 named=1 # [], {named: 1, named2: 2, third: 3}1,
*** Test Cases *** # args, kwargs Named-only only Dynamic named=value # [], {named: value} Dynamic named=value named2=2 # [], {named: value, named2: 2} Named-only with positional and varargs Dynamic argument named=xxx # [argument], {named: xxx} Dynamic a1 a2 named=3 # [a1, a2], {named: 3} Named-only with normal named Dynamic named=foo positional=bar # [], {positional: bar, named: foo} Named-only with free named Dynamic named=value foo=bar # [], {named: value, foo=bar} Dynamic named2=2 third=3 named=1 # [], {named: 1, named2: 2, third: 3}2,
*** Test Cases *** # args, kwargs Named-only only Dynamic named=value # [], {named: value} Dynamic named=value named2=2 # [], {named: value, named2: 2} Named-only with positional and varargs Dynamic argument named=xxx # [argument], {named: xxx} Dynamic a1 a2 named=3 # [a1, a2], {named: 3} Named-only with normal named Dynamic named=foo positional=bar # [], {positional: bar, named: foo} Named-only with free named Dynamic named=value foo=bar # [], {named: value, foo=bar} Dynamic named2=2 third=3 named=1 # [], {named: 1, named2: 2, third: 3}3Các đối số sau các biến thể hoặc một số duy nhất
*** Test Cases *** # args, kwargs No arguments Dynamic # [], {} Positional only Dynamic x # [x], {} Dynamic x y # [x, y], {} Free named only Dynamic x=1 # [], {x: 1} Dynamic x=1 y=2 z=3 # [], {x: 1, y: 2, z: 3} Free named with positional Dynamic x y=2 # [x], {y: 2} Dynamic x y=2 z=3 # [x], {y: 2, z: 3} Free named with normal named Dynamic a=1 x=1 # [], {a: 1, x: 1} Dynamic b=2 x=1 a=1 # [], {a: 1, b: 2, x: 1}5 nếu không có các biến thể. Có hoặc không có mặc định. Yêu cầu
run_keyword
để. Mới trong Robot Framework 3. 1. *** Test Cases *** # args, kwargs Named-only only Dynamic named=value # [], {named: value} Dynamic named=value named2=2 # [], {named: value, named2: 2} Named-only with positional and varargs Dynamic argument named=xxx # [argument], {named: xxx} Dynamic a1 a2 named=3 # [a1, a2], {named: 3} Named-only with normal named Dynamic named=foo positional=bar # [], {positional: bar, named: foo} Named-only with free named Dynamic named=value foo=bar # [], {named: value, foo=bar} Dynamic named2=2 third=3 named=1 # [], {named: 1, named2: 2, third: 3}6,
*** Test Cases *** # args, kwargs Named-only only Dynamic named=value # [], {named: value} Dynamic named=value named2=2 # [], {named: value, named2: 2} Named-only with positional and varargs Dynamic argument named=xxx # [argument], {named: xxx} Dynamic a1 a2 named=3 # [a1, a2], {named: 3} Named-only with normal named Dynamic named=foo positional=bar # [], {positional: bar, named: foo} Named-only with free named Dynamic named=value foo=bar # [], {named: value, foo=bar} Dynamic named2=2 third=3 named=1 # [], {named: 1, named2: 2, third: 3}7,
*** Test Cases *** # args, kwargs Named-only only Dynamic named=value # [], {named: value} Dynamic named=value named2=2 # [], {named: value, named2: 2} Named-only with positional and varargs Dynamic argument named=xxx # [argument], {named: xxx} Dynamic a1 a2 named=3 # [a1, a2], {named: 3} Named-only with normal named Dynamic named=foo positional=bar # [], {positional: bar, named: foo} Named-only with free named Dynamic named=value foo=bar # [], {named: value, foo=bar} Dynamic named2=2 third=3 named=1 # [], {named: 1, named2: 2, third: 3}8
Khi sử dụng
*** Test Cases *** # args # args, kwargs Positional only Dynamic x # [x] # [x], {} Dynamic x y # [x, y] # [x, y], {} Dynamic x y z # [x, y, z] # [x, y, z], {} Named only Dynamic a=x # [x] # [], {a: x} Dynamic c=z a=x b=y # [x, y, z] # [], {a: x, b: y, c: z} Positional and named Dynamic x b=y # [x, y] # [x], {b: y} Dynamic x y c=z # [x, y, z] # [x, y], {c: z} Dynamic x b=y c=z # [x, y, z] # [x], {y: b, c: z} Intermediate missing Dynamic x c=z # [x, d1, z] # [x], {c: z}4, Robot Framework sẽ tự động tính toán số đối số vị trí mà từ khóa yêu cầu và nó có hỗ trợ đối số được đặt tên miễn phí hay không. Nếu một từ khóa được sử dụng với các đối số không hợp lệ, sẽ xảy ra lỗi và
run_keyword
thậm chí không được gọiTên đối số thực tế và giá trị mặc định được trả về cũng rất quan trọng. Chúng cần thiết và công cụ cần chúng để có thể tạo tài liệu thư viện có ý nghĩa
Như đã giải thích trong bảng trên, giá trị mặc định có thể được chỉ định với tên đối số dưới dạng chuỗi như run_keyword
1 hoặc dưới dạng bộ như run_keyword
2. Vấn đề chính với cú pháp trước là tất cả các giá trị mặc định được coi là chuỗi trong khi cú pháp sau cho phép sử dụng tất cả các đối tượng như run_keyword
3 hoặc run_keyword
4. Khi sử dụng các đối tượng khác ngoài chuỗi, Robot Framework có thể thực hiện dựa trên chúng
Vì lý do nhất quán, các đối số không chấp nhận giá trị mặc định cũng có thể được chỉ định làm bộ một mục. Ví dụ, run_keyword
5 và run_keyword
6 là tương đương
Nếu
*** Test Cases *** # args # args, kwargs Positional only Dynamic x # [x] # [x], {} Dynamic x y # [x, y] # [x, y], {} Dynamic x y z # [x, y, z] # [x, y, z], {} Named only Dynamic a=x # [x] # [], {a: x} Dynamic c=z a=x b=y # [x, y, z] # [], {a: x, b: y, c: z} Positional and named Dynamic x b=y # [x, y] # [x], {b: y} Dynamic x y c=z # [x, y, z] # [x, y], {c: z} Dynamic x b=y c=z # [x, y, z] # [x], {y: b, c: z} Intermediate missing Dynamic x c=z # [x, d1, z] # [x], {c: z}4 bị thiếu hoặc trả về Python
run_keyword
8 cho một từ khóa nhất định, thì từ khóa đó sẽ nhận được một đặc tả đối số chấp nhận tất cả các đối số. Thông số đối số tự động này là run_keyword
9 hoặc get_keyword_names
0, tùy thuộc vào việc có run_keyword
hay khôngGhi chú
Hỗ trợ chỉ định các đối số dưới dạng các bộ như run_keyword
2 là tính năng mới trong Robot Framework 3. 2
Khung người máy 3. 1 đã giới thiệu hỗ trợ chuyển đổi đối số tự động và API thư viện động cũng hỗ trợ điều đó. Logic chuyển đổi hoạt động chính xác như with , nhưng cách thông tin loại được chỉ định là khác nhau một cách tự nhiên
Với các kiểu thư viện động có thể được trả về bằng cách sử dụng phương thức get_keyword_names
3 tùy chọn [bí danh get_keyword_names
4]. Nó có thể trả về các loại bằng cách sử dụng danh sách hoặc từ điển chính xác giống như các loại có thể được chỉ định khi sử dụng. Thông tin loại có thể được chỉ định bằng cách sử dụng các loại thực tế như get_keyword_names
5, nhưng đặc biệt nếu một thư viện động lấy thông tin này từ các hệ thống bên ngoài, thì việc sử dụng các chuỗi như get_keyword_names
6 hoặc get_keyword_names
7 có thể dễ dàng hơn. Xem phần để biết thêm thông tin về các loại được hỗ trợ và cách chỉ định chúng
Robot Framework thực hiện chuyển đổi đối số tự động cũng dựa trên. Trước đó, điều này không hoạt động với API động vì chỉ có thể chỉ định các đối số dưới dạng chuỗi. Như, điều này đã được thay đổi trong Robot Framework 3. 2 và ngày nay các giá trị mặc định được trả về như get_keyword_names
8 được tự động sử dụng cho mục đích này
Thư viện động có thể báo cáo bằng cách sử dụng phương pháp get_keyword_names
9 [bí danh ['first keyword', 'second keyword']
0]. Nó lấy tên từ khóa làm đối số và sẽ trả về các thẻ tương ứng dưới dạng danh sách các chuỗi
Ngoài ra, có thể chỉ định các thẻ trên hàng cuối cùng của tài liệu được trả về bằng phương pháp ['first keyword', 'second keyword']
1 được thảo luận bên dưới. Điều này yêu cầu bắt đầu hàng cuối cùng với ['first keyword', 'second keyword']
2 và liệt kê các thẻ sau nó như ['first keyword', 'second keyword']
3
Mẹo
Phương thức get_keyword_names
9 được đảm bảo được gọi trước phương thức ['first keyword', 'second keyword']
1. Điều này giúp dễ dàng nhúng các thẻ vào tài liệu chỉ khi phương thức get_keyword_names
9 không được gọi
Nếu các thư viện động muốn cung cấp tài liệu từ khóa, họ có thể triển khai phương thức ['first keyword', 'second keyword']
1 [bí danh ['first keyword', 'second keyword']
8]. Nó lấy tên từ khóa làm đối số và, như tên phương thức ngụ ý, trả về tài liệu của nó dưới dạng chuỗi
Tài liệu trả về được sử dụng tương tự như chuỗi tài liệu từ khóa với các thư viện tĩnh. Trường hợp sử dụng chính là đưa tài liệu của từ khóa vào tài liệu thư viện được tạo bởi. Ngoài ra, dòng đầu tiên của tài liệu [cho đến ['first keyword', 'second keyword']
9 đầu tiên] được hiển thị trong nhật ký kiểm tra
Phương pháp ['first keyword', 'second keyword']
1 cũng có thể được sử dụng để chỉ định tài liệu thư viện tổng thể. Tài liệu này không được sử dụng khi các bài kiểm tra được thực thi, nhưng nó có thể làm cho tài liệu được tạo ra tốt hơn nhiều
Thư viện động có thể cung cấp cả tài liệu thư viện chung và tài liệu liên quan đến việc đưa thư viện vào sử dụng. Cái trước nhận được bằng cách gọi ['first keyword', 'second keyword']
1 với giá trị đặc biệt ['first_keyword', 'second_keyword']
2 và cái sau nhận được giá trị sử dụng ['first_keyword', 'second_keyword']
3. Cách trình bày tài liệu được thử nghiệm tốt nhất trong thực tế
Các thư viện động cũng có thể chỉ định trực tiếp tài liệu thư viện chung trong mã dưới dạng chuỗi tài liệu của lớp thư viện và phương thức ['first_keyword', 'second_keyword']
3 của nó. Nếu một tài liệu không trống được lấy trực tiếp từ mã và từ phương thức ['first keyword', 'second keyword']
1, thì tài liệu sau được ưu tiên
API động che giấu việc triển khai thực sự các từ khóa từ Robot Framework và do đó không thể biết được các từ khóa được triển khai ở đâu. Điều này có nghĩa là trình chỉnh sửa và các công cụ khác sử dụng API Robot Framework không thể triển khai các tính năng như chuyển sang định nghĩa. Vấn đề này có thể được giải quyết bằng cách triển khai một phương thức động tùy chọn khác có tên là ['first_keyword', 'second_keyword']
6 [bí danh ['first_keyword', 'second_keyword']
7] trả về thông tin nguồn
Giá trị trả về từ phương thức ['first_keyword', 'second_keyword']
6 phải là một chuỗi hoặc run_keyword
8 nếu không có thông tin nguồn. Trong trường hợp đơn giản, chỉ cần trả về một đường dẫn tuyệt đối tới tệp thực hiện từ khóa là đủ. Nếu biết số dòng nơi bắt đầu triển khai từ khóa, nó có thể được nhúng vào giá trị trả về như ['firstKeyword', 'secondKeyword']
0. Chỉ trả lại số dòng là có thể như ['firstKeyword', 'secondKeyword']
1
Thông tin nguồn của chính thư viện được lấy tự động từ lớp thư viện đã nhập giống như với các API thư viện khác. Đường dẫn nguồn thư viện được sử dụng với tất cả các từ khóa không xác định đường dẫn nguồn riêng
Ghi chú
Trả về thông tin nguồn cho từ khóa là một tính năng mới trong Robot Framework 3. 2
Ngoài ra API thư viện động hỗ trợ. Sử dụng cú pháp hoạt động dựa trên tên đối số và giá trị mặc định bằng cách sử dụng phương thức
*** Test Cases *** # args # args, kwargs Positional only Dynamic x # [x] # [x], {} Dynamic x y # [x, y] # [x, y], {} Dynamic x y z # [x, y, z] # [x, y, z], {} Named only Dynamic a=x # [x] # [], {a: x} Dynamic c=z a=x b=y # [x, y, z] # [], {a: x, b: y, c: z} Positional and named Dynamic x b=y # [x, y] # [x], {b: y} Dynamic x y c=z # [x, y, z] # [x, y], {c: z} Dynamic x b=y c=z # [x, y, z] # [x], {y: b, c: z} Intermediate missing Dynamic x c=z # [x, d1, z] # [x], {c: z}4
Nếu phương thức run_keyword
chấp nhận ba đối số, thì đối số thứ hai nhận tất cả các đối số vị trí dưới dạng danh sách và các đối số cuối cùng nhận tất cả các đối số có tên dưới dạng ánh xạ. Nếu nó chỉ chấp nhận hai đối số, các đối số được đặt tên sẽ được ánh xạ tới các đối số vị trí. Trong trường hợp sau, nếu một từ khóa có nhiều đối số với các giá trị mặc định và chỉ một số đối số sau được đưa ra, thì khung sẽ điền vào các đối số tùy chọn bị bỏ qua dựa trên các giá trị mặc định được trả về bởi phương thức
*** Test Cases *** # args # args, kwargs Positional only Dynamic x # [x] # [x], {} Dynamic x y # [x, y] # [x, y], {} Dynamic x y z # [x, y, z] # [x, y, z], {} Named only Dynamic a=x # [x] # [], {a: x} Dynamic c=z a=x b=y # [x, y, z] # [], {a: x, b: y, c: z} Positional and named Dynamic x b=y # [x, y] # [x], {b: y} Dynamic x y c=z # [x, y, z] # [x, y], {c: z} Dynamic x b=y c=z # [x, y, z] # [x], {y: b, c: z} Intermediate missing Dynamic x c=z # [x, d1, z] # [x], {c: z}4
Việc sử dụng cú pháp đối số được đặt tên với các thư viện động được minh họa bằng các ví dụ sau. Tất cả các ví dụ đều sử dụng từ khóa Động có đặc tả đối số ['firstKeyword', 'secondKeyword']
5. Nhận xét trên mỗi hàng cho biết cách run_keyword
sẽ được gọi trong những trường hợp này nếu nó có hai đối số [i. e. chữ ký là ['firstKeyword', 'secondKeyword']
7] và nếu nó có ba đối số [i. e. ['firstKeyword', 'secondKeyword']
8]
*** Test Cases *** # args # args, kwargs Positional only Dynamic x # [x] # [x], {} Dynamic x y # [x, y] # [x, y], {} Dynamic x y z # [x, y, z] # [x, y, z], {} Named only Dynamic a=x # [x] # [], {a: x} Dynamic c=z a=x b=y # [x, y, z] # [], {a: x, b: y, c: z} Positional and named Dynamic x b=y # [x, y] # [x], {b: y} Dynamic x y c=z # [x, y, z] # [x, y], {c: z} Dynamic x b=y c=z # [x, y, z] # [x], {y: b, c: z} Intermediate missing Dynamic x c=z # [x, d1, z] # [x], {c: z}
Ghi chú
Trước Robot Framework 3. 1, tất cả các đối số được đặt tên thông thường được ánh xạ tới các đối số vị trí và tùy chọn ['firstKeyword', 'secondKeyword']
9 chỉ được sử dụng với các đối số được đặt tên miễn phí. Với các ví dụ trên, run_keyword
luôn được gọi như ngày nay nếu nó không hỗ trợ ['firstKeyword', 'secondKeyword']
9
Thư viện động cũng có thể hỗ trợ [
class DynamicExample: def get_keyword_names[self]: return ['first keyword', 'second keyword'] def run_keyword[self, name, args, kwargs]: print["Running keyword '%s' with positional arguments %s and named arguments %s." % [name, args, kwargs]]02]. Điều kiện tiên quyết bắt buộc đối với hỗ trợ này là phương pháp
run_keyword
. cái thứ ba sẽ nhận được các đối số được đặt tên miễn phí cùng với các đối số được đặt tên khác có thể. Các đối số này được chuyển đến từ khóa dưới dạng ánh xạĐối số nào mà từ khóa chấp nhận phụ thuộc vào điều gì
*** Test Cases *** # args # args, kwargs Positional only Dynamic x # [x] # [x], {} Dynamic x y # [x, y] # [x, y], {} Dynamic x y z # [x, y, z] # [x, y, z], {} Named only Dynamic a=x # [x] # [], {a: x} Dynamic c=z a=x b=y # [x, y, z] # [], {a: x, b: y, c: z} Positional and named Dynamic x b=y # [x, y] # [x], {b: y} Dynamic x y c=z # [x, y, z] # [x, y], {c: z} Dynamic x b=y c=z # [x, y, z] # [x], {y: b, c: z} Intermediate missing Dynamic x c=z # [x, d1, z] # [x], {c: z}4. Nếu đối số cuối cùng bắt đầu bằng
*** Test Cases *** # args, kwargs No arguments Dynamic # [], {} Positional only Dynamic x # [x], {} Dynamic x y # [x, y], {} Free named only Dynamic x=1 # [], {x: 1} Dynamic x=1 y=2 z=3 # [], {x: 1, y: 2, z: 3} Free named with positional Dynamic x y=2 # [x], {y: 2} Dynamic x y=2 z=3 # [x], {y: 2, z: 3} Free named with normal named Dynamic a=1 x=1 # [], {a: 1, x: 1} Dynamic b=2 x=1 a=1 # [], {a: 1, b: 2, x: 1}9, thì từ khóa đó được công nhận để chấp nhận các đối số được đặt tên miễn phí
Sử dụng cú pháp đối số được đặt tên miễn phí với các thư viện động được minh họa bằng các ví dụ sau. Tất cả các ví dụ đều sử dụng từ khóa Động có đặc tả đối số
class DynamicExample: def get_keyword_names[self]: return ['first keyword', 'second keyword'] def run_keyword[self, name, args, kwargs]: print["Running keyword '%s' with positional arguments %s and named arguments %s." % [name, args, kwargs]]06. Nhận xét cho thấy các đối số mà phương thức
run_keyword
thực sự được gọi với*** Test Cases *** # args, kwargs No arguments Dynamic # [], {} Positional only Dynamic x # [x], {} Dynamic x y # [x, y], {} Free named only Dynamic x=1 # [], {x: 1} Dynamic x=1 y=2 z=3 # [], {x: 1, y: 2, z: 3} Free named with positional Dynamic x y=2 # [x], {y: 2} Dynamic x y=2 z=3 # [x], {y: 2, z: 3} Free named with normal named Dynamic a=1 x=1 # [], {a: 1, x: 1} Dynamic b=2 x=1 a=1 # [], {a: 1, b: 2, x: 1}
Ghi chú
Trước Robot Framework 3. 1, các đối số được đặt tên thông thường được ánh xạ tới các đối số vị trí nhưng ngày nay chúng là một phần của ['firstKeyword', 'secondKeyword']
9 cùng với các đối số được đặt tên tự do
Bắt đầu từ Robot Framework 3. 1, thư viện động có thể có. Điều này yêu cầu phương thức run_keyword
. thứ ba nhận các đối số chỉ được đặt tên cùng với các đối số được đặt tên khác
Trong phần trả về của phương thức
*** Test Cases *** # args # args, kwargs Positional only Dynamic x # [x] # [x], {} Dynamic x y # [x, y] # [x, y], {} Dynamic x y z # [x, y, z] # [x, y, z], {} Named only Dynamic a=x # [x] # [], {a: x} Dynamic c=z a=x b=y # [x, y, z] # [], {a: x, b: y, c: z} Positional and named Dynamic x b=y # [x, y] # [x], {b: y} Dynamic x y c=z # [x, y, z] # [x, y], {c: z} Dynamic x b=y c=z # [x, y, z] # [x], {y: b, c: z} Intermediate missing Dynamic x c=z # [x, d1, z] # [x], {c: z}4, các đối số chỉ có tên được chỉ định sau số lượng đối số có thể có [
class DynamicExample: def get_keyword_names[self]: return ['first keyword', 'second keyword'] def run_keyword[self, name, args, kwargs]: print["Running keyword '%s' with positional arguments %s and named arguments %s." % [name, args, kwargs]]11] hoặc dấu hoa thị đơn độc [
*** Test Cases *** # args, kwargs No arguments Dynamic # [], {} Positional only Dynamic x # [x], {} Dynamic x y # [x, y], {} Free named only Dynamic x=1 # [], {x: 1} Dynamic x=1 y=2 z=3 # [], {x: 1, y: 2, z: 3} Free named with positional Dynamic x y=2 # [x], {y: 2} Dynamic x y=2 z=3 # [x], {y: 2, z: 3} Free named with normal named Dynamic a=1 x=1 # [], {a: 1, x: 1} Dynamic b=2 x=1 a=1 # [], {a: 1, b: 2, x: 1}5] nếu từ khóa không chấp nhận varargs. Đối số chỉ được đặt tên có thể có giá trị mặc định và thứ tự của đối số có và không có giá trị mặc định không quan trọng
Việc sử dụng cú pháp đối số chỉ được đặt tên với các thư viện động được minh họa bằng các ví dụ sau. Tất cả các ví dụ đều sử dụng từ khóa Dynamic đã được chỉ định để có thông số đối số
class DynamicExample: def get_keyword_names[self]: return ['first keyword', 'second keyword'] def run_keyword[self, name, args, kwargs]: print["Running keyword '%s' with positional arguments %s and named arguments %s." % [name, args, kwargs]]13. Nhận xét cho thấy các đối số mà phương thức
run_keyword
thực sự được gọi với*** Test Cases *** # args, kwargs Named-only only Dynamic named=value # [], {named: value} Dynamic named=value named2=2 # [], {named: value, named2: 2} Named-only with positional and varargs Dynamic argument named=xxx # [argument], {named: xxx} Dynamic a1 a2 named=3 # [a1, a2], {named: 3} Named-only with normal named Dynamic named=foo positional=bar # [], {positional: bar, named: foo} Named-only with free named Dynamic named=value foo=bar # [], {named: value, foo=bar} Dynamic named2=2 third=3 named=1 # [], {named: 1, named2: 2, third: 3}
Tất cả các phương thức đặc biệt trong API động được liệt kê trong bảng bên dưới. Tên phương thức được liệt kê ở định dạng gạch dưới, nhưng bí danh camelCase của chúng hoạt động giống hệt nhau