#tkinter
Вопрос:
Я написал приложение — простую игру, в которой пользователь пишет свой вопрос и получает один из ответов, которые случайным образом получаются из списка. Теперь нам нужно сделать тест, который проверил бы функцию случайных ответов: мы сравниваем ее ответ и делаем вывод о том, пустой он или нет (важно проверить: ответ не пустой).
Я не сталкивался с тестированием, даже с простой его версией. Что со мной не так?
import random import tkinter as tk RESPONSES = ['Yes', 'No'] class QuestionsAnswers(tk.Frame): def __init__(self, main): tk.Frame.__init__(self, main) self.main = main # let's create a frame where there will be a field for user questions self.frame_question_answer = tk.Frame(master=self.main) # let's create a frame that forms an area with answers to the user's questions self.frame_answer = tk.Frame(master=self.main) # let's add a Text widget - an area for writing questions self.text_box_question = tk.Text(self.frame_question_answer) # widget for displaying random answers self.text_box_answer = tk.Text(master=self.frame_answer) # let's create an element of the Ask button self.button_ask = tk.Button(master=self.frame_question_answer, text='Ask') # creating a Clear button element self.button_clear = tk.Button(master=self.frame_question_answer, text='Clear') # bind all widgets to the grid self.frame_question_answer.grid(row=0, column=0, columnspan=1, sticky='e') self.frame_answer.grid(row=0, column=1, columnspan = 1,sticky='w') self.text_box_question.grid(row=0, column=0, sticky='news') self.text_box_answer.grid(row=0, column=0, sticky='news') self.button_ask.grid(row=3, column=0, sticky='ew') self.button_clear.grid(row=3, column=1, sticky='ew') # binding the event processing to the button self.button_ask.bind('lt;Buttongt;', self.questionQuery) # we bind the command to the button for clearing the question and answer fields self.button_clear.bind('lt;Buttongt;', self.clearText) # The handler of the user's question def questionQuery(self, event): question = self.text_box_question.get('1.0', tk.END) # reading the text from the widget self.main.update_idletasks() self.main.after(2000, lambda: self.button_ask.configure(text='Ask')) if not question.strip(): self.text_box_answer.insert(tk.END, 'Ask your questionn') else: self.answerQuery() # Random response return function def answerQuery(self): time.sleep(2) self.text_box_answer.insert(tk.END, 'Hmm...' 'n') # output to the widget self.main.update_idletasks() time.sleep(2) self.text_box_answer.insert(tk.END, 'I look beyond the twists of fate' 'n') self.main.update_idletasks() self.main.after(2000, lambda: self.text_box_answer.insert(tk.END, random.choice(RESPONSES) 'n')) # the function of clearing the question and answer fields def clearText(self, event): time.sleep(1) self.text_box_question.delete('1.0','end') time.sleep(1) self.text_box_answer.delete('1.0', tk.END) if __name__ == '__main__': window = tk.Tk() quest_answer = QuestionsAnswers(window) window.update() window.mainloop()
Затем я пишу тестовый код:
import unittest class TKinterTestCase(unittest.TestCase): def setUp(self): self.questionsAnswers = QuestionsAnswers() def test_answerQuery(self): self.assertEqual(self.questionsAnswers.answerQuery(), len(self.questionsAnswers.answerQuery())!=0) if __name__ == '__main__': unittest.main()
Тест был пройден, но он выдал ошибку, хотя ее и не должно было быть. Это почему?
Комментарии:
1. Ваша
answerQuery()
функция никогда ничего не возвращает, так что так будет всегдаNone
.2. Это не так. Функция выдает случайный ответ. Приложение работает
3. Это буквально ничего не возвращает. Нет никакого
return
заявления.4. Да, но функция записывает ответы в само приложение. Он возвращает ответы приложению, а не коду
5. Да, но ваш тест проверяет то, что он возвращает , а не то, что он делает .
Ответ №1:
рассмотрим эту строку вашего тестового кода:
self.assertEqual(self.questionsAnswers.answerQuery(), len(self.questionsAnswers.answerQuery())!=0)
Вы утверждаете о том, что answerQuery
возвращается. Поскольку у функции нет return
оператора, она возвращается None
. Ваше утверждение функционально идентично assertEqual(None, len(None)!= 0)
.
Вместо этого вам нужно утверждать о побочных эффектах функции. Поскольку функция в конечном счете добавляет текст в текстовый виджет, вам необходимо подтвердить содержимое текстового виджета. Это может выглядеть примерно так:
actual = self.text_box_answer.get("1.0", "end-1c") self.assertEqual(actual, "whatever you expect it to be")
Поскольку заголовок вопроса заключается в том, как проверить, что ответ не пустой, вы можете просто указать длину результата:
self.assert(len(actual) gt; 0)
… или более питонические:
self.assert(actual)
Комментарии:
1. Спасибо! Меня беспокоит вопрос: чего я могу ожидать, когда функция выбирает ответы случайным образом? Например, я скажу тесту, что жду ответа, но на самом деле в результате случайного выбора ответ B будет передан в текстовый виджет, и тест не сойдется
2. Учитывая неизвестный результат выбора ответов, я пытаюсь построить тест на том факте, что ответ есть (независимо от того, какой из них доступен).
3. по какой-то причине я получаю синтаксическую ошибку с указателем на self.assert. Насколько верным будет следующий проверочный код:
actual = self.test_box_answer.get("1.0", "eng-1c") self.assertisnotnone(actual)