python - 什么样的单元测试对 python 中的聊天机器人有意义?
问题描述
我现在正在创建一个简单的聊天机器人,现在我想使用 unittests 包对其进行测试。我是编程新手,最近才听说单元测试的存在。我认为对于要测试的聊天机器人,看看它是否为正确的用户输入提供了正确的输出是有意义的。因此,例如,如果用户写“Hi”,它应该输出“Hey what's up?” 如库中指定的(我已经为它编写了一堆库;它不是深度学习机器人)。
这是我的聊天机器人的代码:
# importing regular expression operations, which we need later to access the libraries
import re
import random # later we want to pick a chatbot answer to a statement by random
from Jordan_Library import dict_smalltalk, dict_caring, dict_cursing, dict_meditating, dict_corona # import libraries
# and here we imported all the topic libraries
class JordanBot:
"""
A class that represents the abilities of Jordan the chatbot.
...
Attributes
----------
name : str
user can insert name, which will later be shown in the chat.
Methods
----------
name : str
user can insert name, which will later be shown in the chat.
"""
def __init__(self, name): # this function is always called when a new object of the class is called
"""
Constructing topics for Jordan. Takes the user's name as an argument.
"""
self.name = name
def chat(self):
"""
A function that enables chatting with Jordan after picking a topic.
Take no arguments.
"""
topics = [dict_smalltalk, dict_caring, dict_cursing, dict_meditating, dict_corona]
while True:
print("Welcome. My name is Jordan. You can now choose a topic that we can talk about.")
print("Press '0' to have some good old-fashioned smalltalk.")
print("Press '1' to tell me about your deepest sorrows and your destroyed soul.")
print("Press '2' to curse with me.")
print("Press '3' to meditate with me.")
print("Press '4' to talk about Corona.")
# execute this welcome text and tell user what to press in order to pick a topic.
choice = input(">>> ")
# initialize input
if choice == '0': # determine which key to press to initiate the specific topic
print("Alrighty, let's do some chitchatting.")# initiate welcome text for specific topic
print("Don't forget that I am sensitive to punctuation.")
elif choice == '1':
print("Please tell me about your deepest sorrows and your destroyed soul.")
print("Don't forget that I am sensitive to punctuation.")
elif choice == '2':
print("Make yourself ready. let's insult each other!")
print("Don't forget that I am sensitive to punctuation.")
elif choice == '3':
print("Ok then, let's meditate.")
print("Don't forget that I am sensitive to punctuation..")
elif choice == '4':
print("Let's talk about Corona.")
print("Don't forget that I am sensitive to punctuation..")
elif choice == 'q': # if user wants to quit
break
else: # if user pressed the wrong key.
print("Try again.")
edition = topics[int(choice)]
statement = list(map(lambda x:re.compile(x[0], re.IGNORECASE), edition))
# list(map()) applies a function to all elements of a specified object, in this case the cursing library
# lambda makes sure that re.compile is applied in a certain way to all elements of the library without being case-sensitive
# re.compile makes sure that the elemets are turned into objects that can be matched later to another item in the library
answer = list(map(lambda x:x[1], edition))
# same here, but here we pick the second argument in the list x[1], which entails Jordan's answers
while True:
userInput = input(' ' + self.name + ' >>> ') # this allows for the user to type in keys
resp = "I did not understand what you said. Also, I am sensitive to punctuation." # initalize response variable
counter = 0 # initalize counter
while resp == "I did not understand what you said. Also, I am sensitive to punctuation." and counter < len(statement): # determine when to start my loop
for i in range(0, len(statement)): # loop through the indexed library
match = statement[i].match(userInput) # look if input of the user matches with one of the words in the library
if match:
word = statement[i].split(userInput)[1] # We have to take the first element of this list
resp = random.choice(answer[i]) # if there is a match, pick a random answer from x[1]
counter += 1 # make sure that the counter is now + 1 so it does not write the initialized response from the beginning but continues with the loop
# if there is no match though, then it will write the initialized answer
if userInput == 'q':
print(random.choice(answer[i]))
print("---------------------------------")
print("Do you want to choose another topic? Pick below or press 'q' to quit for realsies.")
print("---------------------------------")
break
resp = resp.format(word)
print('____________')
print(' ')
print('Jordan >>> ' + resp) # print Jordan's answer
我正在尝试创建的单元测试类似于:
import unittest
from Jordan_Library import dict_smalltalk, dict_caring, dict_cursing, dict_meditating, dict_corona # import dictionairies
from Jordan_Class import JordanBot
class testJordan(unittest.TestCase):
"""
A class to test several units of Jordan to make sure everything is working correctly.
"""
def test_match(self):
j = JordanBot('StringName')
j.chat()
user_input = "What are you?"
bot_output = list(map(lambda x:x[1], dict_smalltalk)) # this is how I access the right response in the right library
matched = bot_output.match(user_input)
self.assertIn("I am a chatbot, dude. What do you think?", matched)
def test_regex(self):
j = JordanBot('StringName')
j.chat()
text = 'something'
regex = {}
self.assertRegexpMatches(text, regex)
if __name__ == '__main__':
unittest.main()
主要问题是这些行只运行我的代码,而不是真正的任何单元测试。非常感谢您的建议!
解决方案
推荐阅读
- android - android上CoordinatorLayout中RecyclerView下方的底部视图
- python - 在 Wagtail 中将图像再现设置为中心裁剪
- c# - 具有两个相反 WHERE 条件的左外连接 + 子查询
- sql - 错误:缺少表“fetched_row”的 FROM 子句条目
- django - 如何使用 django 后台任务登录?
- gremlin - 公共顶点的 Gremlin 交点
- vue.js - 使用 Axios 在 Vuetify v-data-table 中未显示 JSON 数据
- python - 程序无法比较用户输入和文件是否有原因?
- assembly - nasm 检测到 eof,读取数据块
- google-apps-script - 在 Google App Scripts 中创建的 Google Forms 是否有每日配额?