Как управлять QFileDialog, используя Qt Test?

У меня есть 2 вопроса:

  1. Как я могу получить доступ к QFileDialog и записать путь к файлу в поле «Имя файла» с помощью модуля Qt Test?

    Я спрашиваю об этом, потому что я разрабатываю некоторые тесты GUI в Qt, и теперь мне нужно открыть текстовый файл. Следующий код создает QFileDialog и получает путь к файлу:

    QString filePath = QFileDialog::getOpenFileName(
    this,
    "Open",
    "",
    tr("Text Files (*.txt)") );
    
  2. Если я использую тему (QThread) чтобы загрузить содержимое этого текстового файла, как мне дождаться окончания этой темы в моих тестах GUI?

    Я знаю, что могу использовать QTest::qSleep( milliseconds ); команда, но я не думаю, что это хорошая практика в этом случае.

По возможности покажите мне пример, пожалуйста.

1

Решение

  1. К сожалению, это невозможно с помощью модуля Qt Test. У вас есть несколько вариантов:

    1. Добавьте тестовые перехватчики, которые пропускают это диалоговое окно: вам нужно использовать свой код, чтобы сделать его тестируемым. Вы могли бы, например, установить testFile свойство объекта, который запрашивает у файла путь к файлу, если свойство установлено, объект может пропустить запрос файла.

      const char k_testFile[] = "k_testFile";
      
      MyClass::foo() {
      ...
      auto testFile = property(k_testFile);
      auto filePath = testFile.isNull()
      ? QFileDialog::getOpenFilePath(...)
      : testFile.toString();
      ...
      }
      
    2. Используйте не родной диалог, и тогда это обычный виджет, который вы можете протестировать с помощью Qt Test.

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

  2. Вы должны испустить сигнал после загрузки файла. Тест может ждать этого сигнала. Вам даже не нужно использовать явный поток для загрузки файла, идиоматический способ асинхронной загрузки файла:

    QString filePath = ...;
    QtConcurrent::run(ioPool, [this, filePath]{
    auto data = MyLoader::load(filePath);
    emit haveFileData(data);
    });
    

    Класс, в котором вы вызываете этот код, должен иметь haveFileData сигнализировать, что какой-то другой код подключается и работает по желанию. ioPool это пул потоков, используемый для операций ввода-вывода, это может быть QThredPool::globalInstance() если вы хотите, чтобы глобальный пул был пулом ввода-вывода. Пулы потоков, связанные с процессором и вводом-выводом, должны быть разделены.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]