Рубрики
Без рубрики

Притворяться Пока ты не сделаешь это

Возьми? Потому что мы издеваемся над тем? Тем не мение. Напишите тесты. Не так много. В основном интеграция. – Кент … с меткой OpenSource, Testing, Python, Java.

Возьми? Потому что мы издеваемся над тем? Тем не мение.

Напишите тесты. Не так много. В основном интеграция. – Кент С. Доддс – Гвидо Ван Россум

Вы когда -нибудь играли в Dungeons & Dragons? Я пробовал несколько раз, но, по крайней мере, из партии, похоже, не может оставаться вложенным как я. Это отстой. Я надеюсь, что, как только все это поразит, я могу попробовать играть снова лично. В любом случае, причина, по которой я спрашиваю, вы когда -нибудь чувствовали себя персонажем в фильме? Как насчет игры? Книга? Кампания D & D? Вы мастер подземелья или игрок? Кто ты Действительно ? Я действительно устал. Это только вторник ( после написания этой первой итерации ), и я уже сгорел. Может быть, медленно теряет мой разум.

В любом случае, на этой неделе кампания приключениелаборатория Мы экспериментируем с модульными тестированием и непрерывной интеграцией, лабораторией, которую я ждал весь этот семестр. Мне всегда очень нравилась сторона DevOps, так как я всегда возился с аппаратными или новыми программными приложениями, и я всегда хотел провести некоторое тестирование программного обеспечения, поэтому, естественно, я взволнован.

Мы должны интегрировать модульные тесты в нашем личные проекты , добавьте модульные тесты, добавьте модульные тесты в проект другого студента и, наконец, добавьте CI в наш репо GitHub.

Естественно, первым шагом было исследование структур тестирования для Python (как написан мой проект на Python.) Я действительно обнаружил, что Python имеет встроенную структуру модульных тестов, творчески названную Unittest … Ну, по крайней мере, это не глупые описательно умное, но соответствующее имя . Итак, я начал с этого, но я нашел синтаксис и выходные данные о неуклюже Поэтому я решил посмотреть, какова была новая жаркость: введите Pytest Анкет ( Честно говоря, я выбрал это, потому что некоторые парни на Reddit сказали мне, что это здорово. Я новичок Студент, подать мне в суд. )

Я начал свое приключение, делая Привет, мир модульных тестов, которые сработали хорошо. Затем я попытался применить свои знания в своем проекте и настроить свою среду, где я столкнулся с некоторыми странными проблемами с тем, как Python структурирует их каталоги и код. Видите ли, Pytest любит вещи определенным образом. Тесты файлов должны начинаться с test_ Префикс, каталоги должны содержать __init__.py Файл и тесты не могут быть в каталоге выше, чем в каталоге, в котором вы тестируете (например, тесты не могут находиться в папке в папке Source … что кажется нелогичным, увы, был столь же стабильным, как Чарльз Мэнсон (Однажды в Голливуде было замечательно, иди посмотри.) ) Я также должен был сделать какой -то странный хак Что я не понял, для которого Питон закричал, что иногда не может найти библиотеку, а в другом – это могло. С настройкой среды я решил сделать некоторые тесты.

Я решил начать с написания теста на небольшую функцию загрузчика файлов в моем проекте. Функция принимает два файла: HTML -страница, содержащая ссылки для проверки состояния, и текстовый файл ссылок, которые вы Не хочу проверить состояние в файле HTML. Поэтому я думаю, что первый тест, чтобы увидеть, действительно ли эта функция работает, как и ожидалось, состоит в том, чтобы дать ей плохие файлы для проверки.

def test_file_check_ignored_empty_files():
    with pytest.raises(FileNotFoundError):
        fio.file_check_ignored("", "")

Функция печатает сообщение и бросает ошибку, если это произойдет … Итак, почему мой тест не показал этого? Оказывается, вам действительно нужно позвонить поднимать Если вы хотите бросить определенную ошибку … с помощью этой фиксированной в моей функции тест теперь работает правильно. Потрясающий! Теперь давайте проведем тест, чтобы убедиться, что выходные данные совпадают, то есть функция фактически работает должным образом:

def test_file_check():
    tested_output = '
\n\n\n\nHeader\n\n\n\n Working link here \n However, this line (and link) should be ignored. \n\n\n'
    soup = fio.file_check("tests/test1.html")
    assert str(soup) == tested_output

И вот фактический HTML, с которым мы сравниваем:

Большой! Этот соответствует HTML и проходит, что означает, что файл правильно считывается функцией. Если что -то пойдет не так с тем, как обрабатываются файлы, этот тест позволит нам знать, так как будут различия в выводе, в результате чего тест не пройдет. Теперь давайте перейдем к чему -то более интересному: высмеивая сетевые ответы, чтобы убедиться, что ответ 404 на самом деле читается как ответ 404 по программе, но сначала мы должны немного узнать о том, что такое приспособление, и немного о монахах.

Приспособление похоже на среда Анкет Приспособление будет настраиваться до выполнения тестов, так как каждая функция должна быть протестирована в повторяемой, но идентичной среде тестирования. Например, если мы тестируем функцию, которая добавляет сообщение на веб -сайт, мы должны настроить среду, чтобы имитировать сообщение, вставляемое в базу данных, так что вся встречающаяся информация (время размещена, дата, публикация и т. Д. об этом посте можно учитывать и проверить. По сути, мы должны установить мир до определенного состояния, затем проверить, а затем вернуться в исходное состояние после тестирования. Чтобы правильно использовать наше приспособление, мы должны обезьяна Наш тест.

Обезделок динамически изменяет часть программы во время выполнения, поэтому условия окружающей среды отражаются при тестировании. Если приспособление похоже на создание комнаты для тестирования, патч обезьян будет украшать комнату, поэтому Обезьяна Быть протестированным имеет один и тот же (и полезный) опыт каждый раз. Ты обезьяна. Возвращайся к работе. Особенно полезно для подходов (издевательства) внешних библиотечных вызовов. Итак, возвращаясь к поставленной задаче, как мы создаем нашу программу считать Это тестирует веб -сайт? Легко: мы создаем среду, которая имитирует неудачный вызов ответа (404.):

  1. Сделайте класс, который содержит член status_code, равный 404 (код ответа, который мы хотим.)
  2. Создайте функцию, которая вызывает этот класс
  3. Установите ответ .get Метод из библиотеки запросов для использования mock_get вместо (Это сбрасывается в нормальное состояние после выхода из функции)
  4. Позвоните в нашу функцию нормально и проверьте, является ли код ответа 404 (спойлеры: это будет потому, что мы их согласны.)

Вот как это выглядит в действии:

import requests

def test_get_request_404(monkeypatch):
    """
    Monkeypatches a version of hdj_linkchecker.py's single_link_check() function,
    suchthat the request is always 404 for a given link.
    """

    # Create a mocked object with an http status_code of 404.
    class MockResponse:
        def __init__(self):
            self.status_code = 404

    # Serve the object when called using a monkeypatch
    def mock_get(url):
        return MockResponse()

    # Create a monkeypatch fixture
    monkeypatch.setattr(requests, "get", mock_get)

    assert lc.single_link_check("https://google.ca") == 404

И вот фактическая тестируемая функция:

def single_link_check(url):
    req = requests.get(url)
    return req.status_code

Забавно, как тестовая функция в конечном итоге в 4 раза дольше, чем фактическая функция.

Круто, так что работает. Мы можем попытаться изменить 404 на что -то другое, например, 666, что, будучи небесным в естественных, на самом деле не является реальным кодом ответа. Использование 666 делает тест неудачным, так как наш обезьян теперь утверждает нечто иное, чем ожидалось.

А теперь с тем, что наш путь, время для Storytime :

В относительно ясную, несколько темную ночь, которая была в остальном довольно особенным и не очень зловещим, студент ( с полной головой волос ) намеревался проверить другую функцию. Он быстро столкнулся с кирпичной стеной: «Почему! Почему ты не удаляешь ссылки, как должны ?? “Он закричал. Видите ли, у функции была одна простая работа ( Или, он думал ): возьмите список ссылок, удалите ссылку из файла HTML, если она соответствует ссылке, а затем протестируйте все, что осталось. ” Так почему вы не удаляете никаких ссылок? Ты работаешь просто отлично Когда называется нормально! ” Но, дорогой Хамф, вы видите, что он был обманут, для другой функции была сделана. В земле Мордор Торонто, в пожарах Маунт -Doom Колледж Сенека, Темный лорд Саурон … Подожди, невысокая Анкет На самом деле была другая функция, которая обернулась вокруг этой функции и сделала удаление … Поэтому, естественно, эта функция возвращает тот же выход, что и вход, все, что она делает, это возвращают ссылки. Не удалять их. ” Моя гордость. Моя жадность “. Он думал, когда проклинал дурака, который написал эту программу. Мораль истории, ты Действительно должен знать, как работает ваша программа.

TL; DR: Если вы пишете функцию, которая выполняет x и имеет другую функцию, которая выполняет Y, напишите тест на x вместо слепого приближения Y. Напишите один для Y тоже, просто убедитесь, что вы тестируете фактический вывод, а не то, что, по вашему мнению, он должен выводить.

Так что это было как 2 часа впустую. Мог бы наблюдать за Властелин колец. Или глядя на красивые диаграммы.

Говоря о красивых диаграммах, давайте создадим отчет о покрытии кода, чтобы увидеть, сколько ( Little ?) работа, которую мы проделали. Удивительно, но я думал, что у Pytest будет встроен встроенный, а скорее полагается на внешнюю библиотеку под названием pytest-cov , который может сделать несколько довольно аккуратных вещей, таких как экспорт отчета в HTML для публикации позже. Прищеивание вниз

С установленной библиотекой, я забежал pytest-cov-report temssing tests/ Чтобы генерировать отчет о покрытии на моем SRC каталог:

Удивительно, но у Pycharm есть встроенный инструмент покрытия, который показывает вам, сколько вашего исходного кода покрывается тестами на панели обозревателя файлов слева (просто щелкните правой кнопкой мыши на тестовой папке и нажмите Запустить 'pytest' в тестах ) Я также добавил несколько конфигураций проекта в PYCHARM, поэтому щелчок правой кнопкой мыши на любом тестовом файле позволяет запустить его и отображать вывод, а не открывать консоль и печатать питест (Хотя я также добавил кнопку для этого, которая может быть переключена с shift+f10 ).

Прохладный. Теперь у нас есть некоторые тесты и отчет о покрытии. Что дальше? Ну, давайте добавим действие GitHub в наш репо Таким образом, мы можем запускать эти тесты каждый раз, когда в нашем коде выполняется запрос на тягу.

Честно говоря, процесс был очень легким. Разочато легко, если честно. Я просто зашел на страницу действий в своем репо и добавил рабочий процесс для моего приложения Python:

Затем он сгенерировал python-package.yml Файл, который я настраивал его по своему вкусу. Я указал использовать только Python 3.6, 3.7, 3.8 и 3,9 в качестве минимальной версии, с которой мой проект будет работать Python 3.6. Я также сказал действию, чтобы запустить Flake8 , черный и питест на каждом коммите:

# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions

name: Python package

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

jobs:
  build:

    runs-on: ubuntu-latest

    strategy:
      matrix:
        python-version: [3.6, 3.7, 3.8, 3.9]

    steps:
    - uses: actions/checkout@v2
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v2
      with:
        python-version: ${{ matrix.python-version }}
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install flake8 pytest
        if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
    - name: Code Format with black
      run: |
        # stop the build if there are any code formatting issues
        black --check .
    - name: Lint with flake8
      run: |
        # stop the build if there are Python syntax errors or undefined names
        flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
        # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
        flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
    - name: Test with pytest
      run: |
        pytest

Тогда я просто подтолкнул его к своему репо, и, как и магия, это сработало:

Woohoo.

Я на самом деле настроил это перед проведением каких -либо тестов, что побудило меня к спамке, что все мои тесты провалились, ха -ха. Причина, по которой это не удалось, заключалась в том, что у меня не было тестов … дух Анкет Но как только я сделал эту сладкую, сладкую рефейзу, слияние, совершение и толкание, он начал запускать мои тесты и давать этот восхитительный зеленый гамбайт.

Со всем обновленным и работающим, моей последней задачей было Обновите мой Anplying.md Файл, чтобы другие разработчики знали, как структурирован мой проект и как работает тестирование.

С учетом моего проекта, теперь пришло время добавить тесты в проект другого студента. Время поразить старый пыльный пламен для еще некоторых Java.

Я не был слишком уверен, с чего начать с тестирования Plamen’s Программа проверки ссылок , так как это сильно изменилось с тех пор, как он И я в последний раз работал вместе. После того, как я быстро пережил, я увидел, что большая часть его проекта не проверялась (в частности, С тех пор, как я работал над этим в предыдущей лаборатории, я был довольно знаком с концепцией того, как это работает, но я попросил немного освежить.

В классе я тестирую FileArgParser и Urlargparser функции. Поскольку Plamen повторно фактировал свой код в лаборатории 6, он переместил их в другой файл и немного изменил их. Теперь функции нуждаются в передаче в Webdriver Аргумент, поэтому я подумал, что мне нужно было издеваться над Webdriver . Я должен был немного обсудить этот подход с ним.

Было трудно узнать, как именно издеваться над Webdriver Со всеми свойствами, но я подумал, что мне просто нужно было передать его свойствами по умолчанию «высмеиваемых», поскольку они не использовались в фактической логике аргументов синтаксического анализа. Я действительно сделал что -то похожее на это в своем собственном проекте Здесь Анкет Я сделал быстрый поиск в Google о том, как издеваться Webdriver и нашел это Анкет В основном, прежде чем тесты будут выполнены, функция CreateMocks () Издевается над Webdriver :

@Before
public void createMocks() {
    webdriver = mock(WebDriver.class);
}

Я предложил эту идею, ему понравилось, и мы попробовали ее вместе. Я проанализировал, как именно насмешка Webdriver должен был быть сделан и смоделировал мое решение для написания тестов на основе этого. К моему большому удивлению, это сработало безупречно.

Теперь, когда веб -драйвер высмеивается, это только вопрос написания фактических тестов, чтобы проверить все ветвиные случаи для обеих функций, которые я тестирую. Как только все было настроено, это было лишь вопросом утверждения флага возврата функций к тому, что на самом деле возвращается каждая ветвь. Там действительно мало что не так уж и за пределами основных утверждений строк. Как только это было сделано, я сделал свой PR.

Чувствует себя хорошо, чувак. Я еще не проверил, если PR был принят; Моя Java совсем не очень хороша, так что, надеюсь, нет проблем, и я все сделал правильно.

В целом, из небольшого тестирования, которое я провел, используя как Python, так и JavaScript, я обнаружил, что библиотека Jest Testing на JavaScript более интуитивно понятна и проще в использовании, что не означает, что я ненавижу pytest вообще. Это прекрасная библиотека, и делает все, что я хочу, это просто не имеет то же самое, что и Jest делает для меня. Я не могу это объяснить. И это исходит от кого -то, кто не большой фанат JS. Может быть, у меня будет больше опыта однажды, чтобы сформировать фактическое мнение.

Что -то, что я всегда хотел принять в своем коде, было TDD Метод написания кода- хотя я должен сказать, что эта лаборатория дает мне наконец понять, почему большинство разработчиков не заботятся о написании тестов. Это сложно, громоздко, часто на неуклюже и чувствует себя рутиной. Я действительно думаю, что это необходимое зло, поэтому я думаю, что лучше принять эту методологию как можно раньше в любом проекте. Я с нетерпением жду возможности узнать об этом и написать некоторые тесты для моего проекта Capstone в следующем семестре, который, несомненно, разозлить членов моей группы Анкет

Очень понравилась эта лаборатория, и я с нетерпением жду следующей.

Не связанный с обучением, я недавно обратился к разработчику в Твиттере о том, как я мог бы принять участие в Большой эмуляционный проект Анкет Мой C ++ не очень хорош, и что -то более низкое, чем … ну, не существует. Как и мой математический фон. Я собираюсь опубликовать его совет для меня здесь, если кто -то любопытен:

Мой единственный совет – никогда не перестать быть любопытным.

Это звучит как супер консервированный ответ, но на самом деле, причина, по которой я получил эмуляцию, заключалась в том, что мне было очень любопытно, как системы работают, и я хотел попытаться сделать вещи лучше.

Когда я начал работать над Дельфином, у меня не было опыта работы с C ++, у меня действительно было только знание о Java и C#. Когда вы начинаете весело работать над вещами, знаете ли вы, что что -то на самом деле не о чем беспокоиться; Вы получите эти знания с течением времени, пытаясь внести свой вклад в проект.

Вы могли бы попробовать прочитать все статьи C ++ и книги в мире, и я уверен, что вы также узнаете из этого, но без чего -либо, чтобы стимулировать этот материал, это будет хороший способ сгореть.

С точки зрения участия в таких проектах, как Dolphin, Citra или Yuzu, вам не нужно знать все в мире об эмуляторе или системе, чтобы начать вносить свой вклад. Все, что нужно, это «о, [вещь] об этом программном обеспечении, вероятно, может быть улучшено, делая [x]», подумал.

Отличный парень. Или Гал, с отличным советом. Может быть, мы могли бы однажды выпить, это было бы весело.

Я также недавно обнаружил чудеса программирования с плохое настроение + Лофи хип -хоп радио Анкет Настоятельно рекомендую это в сочетании с бутылкой вина и свечей, так что вы можете чувствовать себя буржуазный (При написании плохого кода в нижнем белье, потому что никто больше не покидает их дома) .

Наконец, Tipora удивительна для написания этих блогов. Думаю, я мог бы просто мигрировать от Эвернота на это, потому что Evernote каким -то образом удается стать хуже и хуже, когда проходят дни. Также очень рекомендую это.

Оригинал: “https://dev.to/chrispinkney/fake-it-till-you-make-it-46j0”