Как правильно проверять в unittest, что ответ метода не пуст?

#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)