Python API 테스트 자동화 프레임워크(섹션 5) - JSON 및 JsonPath 사용


제목 이미지의 로고 출처: Python, Requests, JSON, HTTP
이것은python을 사용하여 API 프레임워크를 구축하는 방법에 관한 시리즈의 네 번째 편입니다.
다음 앞부분을 참조하십시오.




  • JSON은 현재 API에서 유효 부하를 요청하고 응답하는 데 사용되는 가장 흔히 볼 수 있는 데이터 형식 중 하나로 이를 더욱 잘 이해하는 데 매우 중요하다.
    JSON 형식에 익숙하지 않은 경우 다음 웹 사이트를 참조하십시오.
    JSON.org 또는 w3 schools
    제가 여기서 간략하게 소개하겠습니다. 이것은 주로 key: value의 데이터 구조로 일부 원시 데이터 유형을 포함합니다. 예를 들어 string, boolean, numbersarray의 데이터 유형은 Python 사전과 매우 유사해 보입니다.
    실제로 중첩된 사전을 사용한 적이 있다면 JSON을 기본적으로 이해할 수 있습니다.😉
    계속하기 전에 API 자동화 JSON 포맷을 처리할 때 자주 나타나는 빠른 정의를 살펴봅시다
  • 파이썬 객체를 JSON으로 인코딩하는 프로세스를 서열화라고 합니다.
  • JSON을 Python 객체로 변환하는 프로세스를 반서열화라고 합니다.
  • 나는 이 용어들이 비슷해 보이고 때로는 곤혹스러울 수도 있다는 것을 안다. 그러나 걱정하지 마라. 이 용어들을 사용할 때 그 비결을 터득하게 될 것이다.

    JSON 사용


    파이썬 표준 라이브러리는 JSON 모듈을 통해 JSON에 대한 기존 지원을 제공합니다
    보통 몇 가지 용례를 만날 수 있다
  • python dict를 전송 요청으로 JSON 형식으로 변환
  • 파일에
  • 을 쓰려면 json.dump()을 사용하십시오.
    python 문자열 을 쓰려면
  • 또는 json.dumps()을 선택하십시오.
  • JSON을python dict로 변환
  • 파일에서
  • 을 직접 읽으려면 json.load()을 사용하십시오.
    python 문자열 을 읽으려면
  • 또는 json.loads()을 선택하십시오.
  • 우리는 이미 2장에서 json.dumps() 방법의 실제 응용을 보았기 때문에 상세하게 소개하지 않을 것이다.

    일반적인 API 테스트 프로세스 이해


    가령 우리가 peopleapi에서 아래의 장면을 자동화하고 싶다면
  • 파일에서 JSON 읽기
  • (테스트나 테스트 데이터 파일 대신 요청 주체를 템플릿으로 저장하고 싶다면 유용할 수 있습니다)
  • 수정 요청
  • 의 일부 매개 변수
  • python dict를 JSON 문자열
  • 으로 변환
  • People api
  • 을 사용하여 JSON 로드를 POST 요청에 전달하여 사용자 만들기
  • 현재 데이터베이스에 있는 모든 사용자를 Getapi
  • 으로 가져오기
  • 새 사용자는 수동으로
  • 을 분석하지 않고 JSON 경로를 사용하여 시스템에 생성되었다고 단언합니다.
    나는 이미 이것을 위해 테스트를 했다.다른 부분을 살펴보겠습니다.

    테스트/데이터/창설자.json


    {
      "fname": "Sample firstname",
      "lname": "Sample lastname"
    }}
    
    
    우선, 우리는tests/data 디렉터리에 create_person.json 파일을 가지고 예시 요청체 (일반적으로 요청 부하라고도 부른다) 를 표시합니다.
    일반적으로 이것은 좋은 모델이다. 왜냐하면 이렇게 하면 테스트에서 요청 주체를 명확하게 언급하는 것을 피할 수 있고 부하가 비교적 크면 테스트 파일의 팽창을 줄일 수 있기 때문이다.

    utils / 파일 리더기.py


    import json
    from pathlib import Path
    
    BASE_PATH = Path.cwd().joinpath('..', 'tests', 'data')
    
    def read_file(file_name):
        path = get_file_with_json_extension(file_name)
    
        with path.open(mode='r') as f:
            return json.load(f)
    
    def get_file_with_json_extension(file_name):
        if '.json' in file_name:
            path = BASE_PATH.joinpath(file_name)
        else:
            path = BASE_PATH.joinpath(f'{file_name}.json')
        return path
    
    
    다음에, 우리는 utils/file_reader.py을 사용하여 함수를 제공할 것입니다. 이 함수는tests/data 디렉터리의 파일 이름을 받아들여 읽고 JSON 문자열을 보낼 수 있습니다.
    여기서는 다음 사항에 유의해야 합니다.
    with path.open(mode='r') as f:
        return json.load(f)
    
    
  • path.open을 사용하는 것이지pythons open 방법을 직접 사용하는 것이 아니라는 것을 주의하십시오.따라서 pathlib module 클래스의 Path 클래스를 활용하면 플랫폼 간 기존 경로를 구축하고 쉽게 사용할 수 있습니다.
  • 파일 확장자가 없으면 get_file_with_json_extension 확장자가 추가됩니다.
  • 마찬가지로 우리는 .json을 사용하여 직접 읽을 수 있는 파일을 주고
  • 을 사용할 수 있는python 대상을 되돌려줍니다
    알겠습니다. 이것은python 대상을 얻는 데 도움이 됩니다.

    테스트.py


    다음은 우리가 테스트에서 그것을 어떻게 사용하는지입니다.
    다음은 완전한 테스트 파일입니다.
    엄청 커 보이는 거 알아요.😏 변경 사항을 포장합시다.
    @pytest.fixture
    def create_data():
        payload = read_file('create_person.json')
    
        random_no = random.randint(0, 1000)
        last_name = f'Olabini{random_no}'
    
        payload['lname'] = last_name
        yield payload
    
    def test_person_can_be_added_with_a_json_template(create_data):
        create_person_with_unique_last_name(create_data)
    
        response = requests.get(BASE_URI)
        peoples = loads(response.text)
    
        # Get all last names for any object in the root array
        # Here $ = root, [*] represents any element in the array
        # Read full syntax: https://pypi.org/project/jsonpath-ng/
        jsonpath_expr = parse("$.[*].lname")
        result = [match.value for match in jsonpath_expr.find(peoples)]
    
        expected_last_name = create_data['lname']
        assert_that(result).contains(expected_last_name)
    
    def create_person_with_unique_last_name(body=None):
        if body is None:
            # Ensure a user with a unique last name is created everytime the test runs
            # Note: json.dumps() is used to convert python dict to json string
            unique_last_name = f'User {str(uuid4())}'
            payload = dumps({
                'fname': 'New',
                'lname': unique_last_name
            })
        else:
            unique_last_name = body['lname']
            payload = dumps(body)
    
        # Setting default headers to show that the client accepts json
        # And will send json in the headers
        headers = {
            'Content-Type': 'application/json',
            'Accept': 'application/json'
        }
    
        # We use requests.post method with keyword params to make the request more readable
        response = requests.post(url=BASE_URI, data=payload, headers=headers)
        assert_that(response.status_code, description='Person not created').is_equal_to(requests.codes.no_content)
        return unique_last_name
    
    

    pytest 클러치로 데이터 설정


    @pytest.fixture
    def create_data():
        payload = read_file('create_person.json')
    
        random_no = random.randint(0, 1000)
        last_name = f'Olabini{random_no}'
    
        payload['lname'] = last_name
        yield payload
    
    
    테스트 방법에 전체 설정 코드를 포함하는 것이 아니라pytest 클러치를 사용하여 데이터를 테스트에 주입하고 있습니다.주의, json.load()이라는 핀셋을 매개 변수로 테스트 방법 create_data에 전달
    우리는 def test_person_can_be_added_with_a_json_template(create_data):을 사용하여python dict를 유효 부하로 가져오고 random module을 사용하여 0에서 1000 사이의 무작위 no를 생성하여 접두사에 추가합니다.
    마지막으로 요청체에서 업데이트한 다음 read_file('create_person.json') 키워드를 사용하여 테스트 방법에 제공합니다
    기본값 None을 사용하여 주체를 얻을 수 있도록 이전에 만든 yield을 수정했습니다. 이 값을 사용하여 create_person_with_unique_last_name 방법으로 JSON 요청 주체를 만들거나 제공하지 않으면 이전에 요청 주체를 생성하는 기능을 보류합니다.

    JSONPath 사용


    마지막으로 사용자를 만든 후에 JSON 경로를 사용하여 JSON에서 값을 추출하는 방법을 봅시다
    # Get all last names for any object in the root array
    # Here $ = root, [*] represents any element in the array
    # Read full syntax: https://pypi.org/project/jsonpath-ng/
    jsonpath_expr = parse("$.[*].lname")
    result = [match.value for match in jsonpath_expr.find(peoples)]
    
    expected_last_name = create_data['lname']
    assert_that(result).contains(expected_last_name))
    
    
    JSON path는 JSON 구조를 길게 끼워 넣는 것을 처리하는 좋은 방법으로 XPath와 비슷한 기능을 제공합니다.이 라이브러리를 프레임에 추가하려면 다음을 추가합니다.
    pipenv install jsonpath-ng
    
    
    다양한 용례에 대한 자세한 내용은 PyPI 페이지 jsonpath-ng을 참조하십시오.

    하나의 예


    우리의 예에서, 우리가 이전과 같은 조작을 실행하려고 한다고 가정하자.i, e. 모든 사람의 이름을 얻고 우리가 원하는 사람이 명단에 있는지 확인하세요.
    우리는 json.dumps() 방법으로 JSON 경로 표현식을 지정할 수 있다
    위 표현식은 다음과 같이 번역할 수 있습니다.
  • parse("$.[*].lname") 뿌리부터
  • $, 어레이
  • 의 모든 요소에서 사용
  • [*].lname이라는 키의 값을 얻었다
  • 실행할 JSON 경로를 얻기 위해서, 우리는 lname 방법을 호출하고 get API 응답에서 JSON 응답을 제공합니다.
    마지막으로, 우리가 예상한 성은 이 사용자 목록에 확실히 존재하고, 찾지 못하면 실패할 것이라고 단언합니다.

    결론


    이 장에서 우리는
  • JSON
  • 정렬 또는 반정렬 방법
  • 조종
  • 으로 향상된 JSON 구문 분석 기능을 제공합니다.
  • 이러한 개념이 어떻게 고객에게 좋은 서비스를 제공할 수 있는지 이해하고 성공적인 API 테스트 프레임워크의 기반을 다져줍니다.
    만약 당신이 이 글이 유용하다고 생각한다면 반드시 친구나 동료와 공유해야 한다. 만약 당신이 생각이 있다면, 나는 트위터에 채팅이나 평론을 기꺼이 할 것이다.다음까지.즐거운 테스트.

    And since this is going on on Christmas of 2020. Merry Christmas and happy holidays! 🎅 🎄 Enjoy


    recruitment.com has created alist of the best freelance websitesto hire Python developers. It is also a helpful resource for those Python developers looking for their next freelance job opportunity. Feel free to check them out

    좋은 웹페이지 즐겨찾기