Skip to content

diffy 接口 diff 测试工具

霍格沃兹测试开发学社

ceshiren.com


Diff 方法论


Diff 测试价值

  • 了解应用变更
  • 对被测结果进行细粒度的断言
  • 无须进行显式断言
  • web app service 都可以应用


Twitter Diffy 工具技术架构图


数据校验 Diff


diff 通用工具 deepdiff

ceshiren.com: diff seveniruby$ deep diff --help
Usage: deep diff [OPTIONS] T1 T2

  Deep Diff Commandline

  Deep Difference of content in files. It can read csv, tsv, json, yaml, and
  toml files.

  T1 and T2 are the path to the files to be compared with each other.

Options:
  --cutoff-distance-for-pairs FLOAT
                                  [default: 0.3]
  --cutoff-intersection-for-pairs FLOAT
                                  [default: 0.7]
  --cache-size INTEGER            [default: 0]
  --cache-tuning-sample-size INTEGER
                                  [default: 0]
  --cache-purge-level INTEGER RANGE
                                  [default: 1]
  --create-patch                  [default: False]
  --exclude-paths TEXT
  --exclude-regex-paths TEXT
  --math-epsilon DECIMAL
  --get-deep-distance             [default: False]
  --group-by TEXT
  --ignore-order                  [default: False]
  --ignore-string-type-changes    [default: False]
  --ignore-numeric-type-changes   [default: False]
  --ignore-type-subclasses        [default: False]
  --ignore-string-case            [default: False]
  --ignore-nan-inequality         [default: False]
  --include-private-variables     [default: False]
  --log-frequency-in-sec INTEGER  [default: 0]
  --max-passes INTEGER            [default: 10000000]
  --max_diffs INTEGER
  --number-format-notation [f|e]  [default: f]
  --progress-logger [info|error]  [default: info]
  --report-repetition             [default: False]
  --significant-digits INTEGER
  --truncate-datetime [second|minute|hour|day]
  --verbose-level INTEGER RANGE   [default: 1]
  --debug
  --help                          Show this message and exit.

自定义细节对比

import yaml
from deepdiff import DeepDiff

import xml.etree.ElementTree as ET


class XMLDiff:
    def diff(self, old, new):
        tree = ET.parse(old)
        old = tree.getroot()
        old_object = self.xml2dict(old)

        tree = ET.parse(new)
        new = tree.getroot()
        new_object = self.xml2dict(new)

        ddiff = DeepDiff(old_object, new_object)
        return ddiff.to_dict()

    def xml2dict(self, root: ET.Element):
        res = {}
        res = {k: v for k, v in root.items() if k in ['resource-id', 'content-desc', 'text', 'class']}
        res['children'] = []
        for child in root:
            res['children'].append(self.xml2dict(child))
        return res


if __name__ == '__main__':
    print(yaml.dump(XMLDiff().diff('old.xml', 'new.xml')))

自动化对比结果

iterable_item_added:
  root['children'][0]['children'][0]['children'][0]['children'][0]['children'][0]['children'][0]['children'][2]['children'][0]['children'][1]['children'][1]['children'][0]['children'][0]['children'][0]['children'][2]['children'][1]:
    children:
      - children:
          - children: []
            class: android.widget.TextView
            content-desc: 4 minutes
            resource-id: com.google.android.apps.messaging:id/message_status
            text: 4 min
        class: android.view.ViewGroup
        content-desc: ""
        resource-id: com.google.android.apps.messaging:id/message_details
        text: ""
    class: android.widget.LinearLayout
    content-desc: ""
    resource-id: com.google.android.apps.messaging:id/message_metadata
    text: ""