Tăng cường cho vòng lặp python

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']['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_namesrun_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_namesrun_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ọi

Tê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_keyword1 hoặc dưới dạng bộ như run_keyword2. 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_keyword3 hoặc run_keyword4. 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_keyword5 và run_keyword6 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_keyword8 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_keyword9 hoặc get_keyword_names0, tùy thuộc vào việc có run_keyword hay không

Ghi chú

Hỗ trợ chỉ định các đối số dưới dạng các bộ như run_keyword2 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_names3 tùy chọn (bí danh get_keyword_names4). 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_names5, 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_names6 hoặc get_keyword_names7 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_names8 đượ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_names9 (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_names9 đượ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_names9 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_keyword8 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