3주차 과제 - 최원준

3주차 과제 결과

2주차 과제에서

        columns += ('project_name',)
        column_headers += ('Project Name',)

        columns += ('user_name',)
        column_headers += ('User Name',)

        projects = {p.id: p.name for p in identity_client.projects.list()}
        users = {u.id: u.name for u in identity_client.users.list()}

        for s in data:
            s.project_name = projects.get(s.project_id, s.project_id)
            s.user_name = users.get(s.user_id, s.user_id)

부분 추가로 인해 테스트에서 통과되지 않는 부분을 해결해야합니다.

openstackclient.tests.unit.compute.v2.test_server.TestServerList.test_server_list_with_vm_state
-----------------------------------------------------------------------------------------------

Captured traceback:
~~~~~~~~~~~~~~~~~~~
    Traceback (most recent call last):

      File "/Users/choiwonjun-macbook/Dev/contribution-academy/OCA-OpenStack/python-openstackclient/openstackclient/tests/unit/compute/v2/test_server.py", line 5201, in test_server_list_with_vm_state
    columns, data = self.cmd.take_action(parsed_args)
                    ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^

      File "/Users/choiwonjun-macbook/Dev/contribution-academy/OCA-OpenStack/python-openstackclient/openstackclient/compute/v2/server.py", line 3062, in take_action
    projects = {p.id: p.name for p in identity_client.projects.list()}
                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^

    TypeError: 'Mock' object is not iterable

server list를 테스트하는 과정에서, 2주차 과제에서 수정한 코드의 identity_client.projects.list() 를 호출하는 과정에서 에러가 발생합니다.

2주차 과제 코드에서는 리스트 형태의 값을 받아 활용하는 반면, 테스트 코드에서는 Mock 객체를 넘겨주기 때문에, 먼저 이 에러를 해결해야합니다.

class TestServerList(_TestServerList):
    def setUp(self):
        super().setUp()

        ...
        # 임시 mocking
        self.identity_client.projects.list.return_value = []
        self.identity_client.users.list.return_value = []

        self.data = tuple(
            (
                s.id,
                s.name,
                s.status,
                server.AddressesColumn(s.addresses),
                # Image will be an empty string if boot-from-volume
                self.image.name if s.image else server.IMAGE_STRING_FOR_BFV,
                self.flavor.name,
                s.project_name, # Column 추가
                s.user_name,    # Column 추가
            )
            for s in self.servers
        )

TestServerList 클래스에서 setUp 메소드를 통해 Mocking을 먼저 진행하고 있습니다.
serverList 에서만 임시로 사용할 identity_client.projects.list()를 리스트 형태로 mocking 해주었습니다. identity_client.users.list()역시 동일하게 처리해주었습니다.

    def test_server_list_with_vm_state(self):
        arglist = [
            '--vm-state',
            'active',
        ]
        verifylist = [
            ('vm_state', 'active'),
        ]

        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
        columns, data = self.cmd.take_action(parsed_args)

        self.kwargs['vm_state'] = 'active'
        self.compute_client.servers.assert_called_with(**self.kwargs)
        self.assertEqual(self.columns, columns)
        self.assertEqual(tuple(self.data), tuple(data))

테스트 코드를 확인해보면
self.columnscolumns
tuple(self.data)tuple(data) 를 서로 비교하고 있으며, 2주차 과제에서 추가해주었던 column들에 대한 값들도 추가해주었습니다.

class TestServer(compute_fakes.TestComputev2):
    def setUp(self):
        super().setUp()

        # Set object attributes to be tested. Could be overwritten in subclass.
        self.attrs = {}

    def setup_sdk_servers_mock(self, count):
        servers = compute_fakes.create_servers(
            attrs=self.attrs,
            count=count,
        )

        # 과제 요구사항에 따라 서버 객체에 project_name과 user_name 속성을 추가합니다.
        for s in servers:
            s.project_name = getattr(s, 'project_id', 'admin')
            s.user_name = getattr(s, 'user_id', 'admin')

        # This is the return value for compute_client.find_server()
        self.compute_client.find_server.side_effect = servers

        return servers

테스트 코드에서 self.columnss.project_names.user_name 을 사용하고 있으므로 임시로 값을 추가해주었습니다.

이후 테스트를 진행해보며 테스트 코드에서 하드코딩되어있는 결과값을 알맞게 수정해주었습니다.

1개의 좋아요