Как записать функциональное испытание для сервиса DBUS, записанного в Python?

Что-то вроде этого должно сделать это:

$fileList = Get-ChildItem -Path c:\temp -Recurse file.txt | Sort-Object LastwriteTime -Descending | select -first 1

The поднимет самый последний на верх списка (используя Sort-Object), а затем, если вы выберете первое в списке, Мы получили ваш последний файл.

12
задан seanhodges 4 February 2009 в 18:48
поделиться

5 ответов

С некоторой справкой из сообщения A Ali мне удалось решить мою проблему. Блокирующийся цикл событий должен был быть запущен в отдельный процесс, так, чтобы он мог прислушаться к событиям, не блокируя тест.

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

Я скорректировал пример в своем вопросе. Это свободно напоминает "test_pidavim.py" пример, но использует импорт для "dbus.glib" для обработки бойких зависимостей от цикла вместо того, чтобы кодировать во всем материале DBusGMainLoop:

import unittest

import os
import sys
import subprocess
import time

import dbus
import dbus.service
import dbus.glib
import gobject

class MyDBUSService(dbus.service.Object):

    def __init__(self):
        bus_name = dbus.service.BusName('test.helloservice', bus = dbus.SessionBus())
        dbus.service.Object.__init__(self, bus_name, '/test/helloservice')

    def listen(self):
        loop = gobject.MainLoop()
        loop.run()

    @dbus.service.method('test.helloservice')
    def hello(self):
        return "Hello World!"


class BaseTestCase(unittest.TestCase):

    def setUp(self):
        env = os.environ.copy()
        self.p = subprocess.Popen(['python', './dbus_practice.py', 'server'], env=env)
        # Wait for the service to become available
        time.sleep(1)
        assert self.p.stdout == None
        assert self.p.stderr == None

    def testHelloService(self):
        bus = dbus.SessionBus()
        helloservice = bus.get_object('test.helloservice', '/test/helloservice')
        hello = helloservice.get_dbus_method('hello', 'test.helloservice')
        assert hello() == "Hello World!"

    def tearDown(self):
        # terminate() not supported in Python 2.5
        #self.p.terminate()
        os.kill(self.p.pid, 15)

if __name__ == '__main__':

    arg = ""
    if len(sys.argv) > 1:
        arg = sys.argv[1]

    if arg == "server":
        myservice = MyDBUSService()
        myservice.listen()

    else:
        unittest.main()
6
ответ дан 2 December 2019 в 20:41
поделиться

Простое решение: не делайте теста единицы через dbus.

Вместо этого запишите свои модульные тесты для вызова методов непосредственно. Это согласуется более естественно с природой модульных тестов.

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

3
ответ дан 2 December 2019 в 20:41
поделиться

Я мог бы быть немного вне моей лиги здесь, так как я не знаю Python и только несколько понимаю, каков этот волшебный "dbus", но если я понимаю правильно, это требует, чтобы Вы создали довольно необычную тестовую среду с runloops, расширенной установкой/разрушением, и так далее.

Решение Вашей проблемы должно использовать насмешку. Создайте абстрактный класс, который определяет Ваш интерфейс, и затем создайте объект из этого для использования в фактическом коде. В целях протестировать, Вы создаете фиктивный объект, связывается через тот же самый интерфейс, но имеет поведение, которое Вы определили бы в целях протестировать. Можно использовать этот подход, чтобы "моделировать" пробежку объекта dbus цикла событий, выполнение некоторой работы, и т.д., и затем затем сконцентрироваться на тестировании, как класс должен реагировать на результат "работы", сделанной тем объектом.

2
ответ дан 2 December 2019 в 20:41
поделиться

Просто необходимо удостовериться, что Вы обрабатываете свой основной цикл правильно.

def refresh_ui():
    while gtk.events_pending():
       gtk.main_iteration_do(False)

Это выполнит gtk основной цикл, пока он не закончил обрабатывать все, а не просто выполнил его и блок.

Для полного примера его в практике, поблочном тестировании интерфейс dbus, идут сюда: http://pida.co.uk/trac/browser/pida/editors/vim/test_pidavim.py

2
ответ дан 2 December 2019 в 20:41
поделиться

Вы также можете очень просто запустить основной цикл в отдельном потоке внутри вашего метода setUp.

Примерно так:

import threading
class BaseTestCase(unittest.TestCase):
    def setUp(self):
        myservice = MyDBUSService()
        self.loop = gobject.MainLoop()
        threading.Thread(name='glib mainloop', target=self.loop.run)
    def tearDown(self):
        self.loop.quit()
2
ответ дан 2 December 2019 в 20:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: