클립보드에 대한 테스트를 GiitHubAction으로 쓰기

안녕하세요.안녕하세요.좋은 아침입니다.LAPAS는 엔지니어 또는 DB의 부적입니다.이 글은 LAPRAS Advent Calendar 2021 다섯째 날의 글이다.
최근에는 redasqlredash를 겨냥하여 CLI를 통해 SQL을 실행하는 도구를 제작하였다.그때의 유닛 테스트는 GiitHub Actions가 실행하려고 할 때 끼워 넣은 점입니다.

샘플 설명


이번에는 클립보드 주변만 확인하고 싶어 최소 구성의 앱을 준비했다.
command.py
import argparse
from pyperclip import copy


def init():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '-t',
        '--text',
        help='text for clipboard',
        required=True,
    )
    args = parser.parse_args()
    return args.text


def main(text_for_clipboard: str):
    copy(text_for_clipboard)
    print(f'copied: {text_for_clipboard}')


if __name__ == '__main__':
    text_for_clipboard = init()
    main(text_for_clipboard)
이런 느낌-t コピーしたい文字列으로 실행하면 클립보드에 문자열이 있을 거예요.
(sample39) denzow@denpad$ poetry run python command.py  -t hello
copied: hello
클립보드 주위에 사용pyperclip.
그리고 이쪽에 대한 거친 테스트 코드입니다.
tests/test_command.py
from unittest import TestCase
from pyperclip import paste

import command


class MainTest(TestCase):

    def test_main(self):
        """
        クリップボードに正常にコピーされるかのテスト
        :return: 
        """
        expected_text = 'copy_target'
        command.main(expected_text)
        self.assertEqual(expected_text, paste())
현지에서도 정상적으로 테스트를 진행할 수 있다.
(sample39) denzow@denpad$ poetry run python -m unittest -vvv
test_main (tests.test_command.MainTest)
クリップボードに正常にコピーされるかのテスト ... copied: copy_target
ok

----------------------------------------------------------------------
Ran 1 test in 0.006s

OK
이것을 제재로 한다.

GiitHubAction의 unittest에서 실행


아무튼 아무 생각 없이 Poetry cache 같은 유닛 테스트를 적당히 넣으면 이런 느낌이 든다.
.github/workflows/unittest.yml
name: unittest

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

jobs:
  unittest:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Install Python 3
        uses: actions/setup-python@v1
        with:
          python-version: 3.9
      - name: Install poetry
        uses: snok/install-[email protected]
        with:
          virtualenvs-create: true
          virtualenvs-in-project: true
      - name: Load cached venv
        id: cached-poetry-dependencies
        uses: actions/cache@v2
        with:
          path: .venv
          key: venv-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }}
      - name: Install dependencies
        run: poetry install
        if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
      - name: unit test
        run: |
          poetry run python -m unittest discover -s tests/
갑자기 실행하면 죽어.
======================================================================
ERROR: test_main (test_command.MainTest)
クリップボードに正常にコピーされるかのテスト
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/runner/work/github-actions-clipboard-sample/github-actions-clipboard-sample/tests/test_command.py", line 15, in test_main
    command.main(expected_text)
  File "/home/runner/work/github-actions-clipboard-sample/github-actions-clipboard-sample/command.py", line 18, in main
    copy(text_for_clipboard)
  File "/home/runner/work/github-actions-clipboard-sample/github-actions-clipboard-sample/.venv/lib/python3.9/site-packages/pyperclip/__init__.py", line 659, in lazy_load_stub_copy
    return copy(text)
  File "/home/runner/work/github-actions-clipboard-sample/github-actions-clipboard-sample/.venv/lib/python3.9/site-packages/pyperclip/__init__.py", line 336, in __call__
    raise PyperclipException(EXCEPT_MSG)
pyperclip.PyperclipException: 
    Pyperclip could not find a copy/paste mechanism for your system.
    For more information, please visit https://pyperclip.readthedocs.io/en/latest/index.html#not-implemented-error 

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (errors=1)
Pyperclip이 기대하는 OS 측면의 포장이 부족합니다.제시된 링크를 보면 xselxclip가 필요하다는 것을 알 수 있다.소스는 이 근처에 있어요.
https://github.com/asweigart/pyperclip/blob/781603ea491eefce3b58f4f203bf748dbf9ff003/src/pyperclip/ init.py#L576-L581
클립보드를 순서대로 터치해 보는 명령선 도구를 사용하는 느낌의 실크입니다.먼저 설치하고 먼저 시도한 것xsel.
--- a/.github/workflows/unittest.yml
+++ b/.github/workflows/unittest.yml
@@ -17,6 +17,9 @@ jobs:
         uses: actions/setup-python@v1
         with:
           python-version: 3.9
+      - name: Install os packages
+        run: |
+          sudo apt-get install -y xsel
       - name: Install poetry
         uses: snok/[email protected]
         with:

그러나 이렇게 되면 결과는 같은 잘못으로 실패한다.xsel 또는 xclip를 사용하려면 DISPLAY가 필요하지만 GiitHubAction이 실행하는 환경에서 출력된 화면이 존재하지 않기 때문에 최종적으로 사용할 수 없습니다.
그곳을 이용하여 가상 디스플레이xvfb를 제작한다.xvfb 자체로 가상의 XWindow를 구축할 수 있고, 촬영 캡처 등 다양한 일들이 가능하지만, 이번에 필요한 부분만 있다면xvfb-run을 통해 가상 디스플레이를 이용하고 싶은 지령을 수행하면 된다.
--- a/.github/workflows/unittest.yml
+++ b/.github/workflows/unittest.yml
@@ -19,7 +19,7 @@ jobs:
           python-version: 3.9
       - name: Install os packages
         run: |
-          sudo apt-get install -y xsel
+          sudo apt-get install -y xsel xvfb
       - name: Install poetry
         uses: snok/[email protected]
         with:
@@ -36,4 +36,4 @@ jobs:
         if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
       - name: unit test
         run: |
-          poetry run python -m unittest discover -s tests/
+          xvfb-run poetry run python -m unittest discover -s tests/
GiitHubAction을 통해 클립보드 테스트를 순조롭게 진행할 수 있습니다.

총결산


오랫동안 썼지만 xselxvfb사의 말만 했다.다만, 밟았을 때 좋은 느낌을 못 받아서 누군가에게 도움이 됐으면 좋겠어요.
이번 샘플 창고는 아래에서 공개할 것이다.
https://github.com/denzow/github-actions-clipboard-sample

좋은 웹페이지 즐겨찾기