pyenv와 tox를 이용하여 여러 환경에서 테스트하기

현재 내 로컬에서는 pyenv, pyenv-virtualenv, autoenv 를 이용하여 파이썬 가상환경을 구축하고 있다. (자세한 방법은 많은 블로그 에서 쉽게 찾을 수 있다.)

그리고 이 pyenv와 tox 를 이용하여 다양한 파이썬 버젼에서 테스트할 수 있는 환경을 구축해볼려고 한다. tox는 자동으로 가상환경을 구축하여 그 환경에서 지정한 명령어를 실행시켜주는 도구이다.

우선 한 프로젝트에서 사용되는 파이썬 패키지들을 관리할 가상환경을 하나 생성하였다.

$ pyenv virtualenv 3.7.0 tox-test

그리고 프로젝트 디렉토리 접근시 자동으로 가상환경을 활성화할 수 있도록 .env 파일에 아래와 같은 스크립트를 추가하였다.

pyenv local tox-test  

그리고 테스트를 위해 테스트 코드를 하나 작성하였다. unittest 공식 문서 에 있는 예제 코드를 그대로 사용하였다.

# test_string.py

import unittest

class TestStringMethods(unittest.TestCase):

    def test_upper(self):
        self.assertEqual('foo'.upper(), 'FOO')

    def test_isupper(self):
        self.assertTrue('FOO'.isupper())
        self.assertFalse('Foo'.isupper())

    def test_split(self):
        s = 'hello world'
        self.assertEqual(s.split(), ['hello', 'world'])
        # check that s.split fails when the separator is not a string
        with self.assertRaises(TypeError):
            s.split(2)

테스트 라이브러리인 nose 를 설치한 후, 테스트를 돌려보면 3개의 테스트가 성공했다는 메시지가 나타날 것이다.

$ pip install nose
$ nosetests
...
----------------------------------------------------------------------
Ran 3 tests in 0.004s

OK  

자 이제, 현재 파이썬 버젼(3.7.0) 뿐만 아니라 다른 환경에서도 위의 테스트 코드가 성공하는지 확인해볼려고 한다.

우선 tox를 설치한 후,

$ pip install tox

$ tox 라고 실행해보면, setup.py 가 없다는 에러가 뜰 것이다. tox는 테스트를 하기전 프로젝트를 packaging하기 때문에 packaging을 위한 설명서가 되는 setup.py 가 있어야만 한다.

아래과 같이 간단하게 setup.py를 작성하였다.

# setup.py

import setuptools

setuptools.setup(  
    name="tox-test",
    version="0.0.1",
    author="jupiny",
    author_email="tmdghks584@gmail.com",
    description="A package for test using tox",
    packages=setuptools.find_packages(),
)

그리고 tox 실행과 관련된 정보를 tox.ini 파일에 작성하면 된다.

[tox]
envlist = py27, py34, py35, py36, py37

[testenv:py27]
basepython = python2.7

[testenv:py34]
basepython = python3.4

[testenv:py35]
basepython = python3.5

[testenv:py36]
basepython = python3.6

[testenv:py37]
basepython = python3.7

[testenv]
deps = nose  
commands = nosetests  

현재 디렉토리 구조는 아래와 같다.

$ tree
.
├── setup.py
├── tox-test
│   ├── __init__.py
│   └── test_string.py
├── tox.ini

다시 $ tox 를 실행하면, 몇몇 파이썬 버젼에서 virtualenv를 생성하는데 실패할 것이다. 나같은 경우는 현재 활성화된 가상환경이 3.7.0 밖에 없기 때문에 py37 를 제외한 모든 버젼에서 실패하였다. 이를 위해 각 버젼에 맞는 가상환경들을 더 생성하여 활성화 시켜야한다.

$ pyenv virtualenv -p python2.7 2.7.12 py27
$ pyenv virtualenv -p python3.4 3.4.4 py34
$ pyenv virtualenv -p python3.5 3.5.2 py35
$ pyenv virtualenv -p python3.6 3.6.6 py36
$ pyenv virtualenv -p python3.7 3.7.0 py37

각 버젼에 해당하는 가상환경들을 추가로 생성하였다. 명령어의 -p pythonX.X 옵션 값과 tox.inibasepython = pythonX.X 부분을 정확히 일치시킨 것에 주목하자. -p 옵션은 가상환경 활성화 시에 실행할 파이썬 파일을 구체적으로 정할 수 있다.

이 가상환경들을 활성화하기 위해 .env 에도 추가하도록 하자.

pyenv local tox-test py27 py34 py35 py36 py37  

맨 앞의 tox-test 가상환경은 파이썬 패키지들을 관리할 목적으로 생성한 가상환경이고, 나머지 뒤의 가상환경들은 tox 실행을 위해 추가한 가상환경이라 생각하면 될 것 같다.

이제 $ tox 를 실행하면,

"congratulations :)" 글자를 볼 수 있을 것이다.

참고