第九章的测试数据发现测试程序无法调用临时数据库,一直使用的本地数据库,导致测试未通过。

查找了很久,改正了些小错误,但是最后测试依旧无法通过,实在找不到哪里有问题,只能推测出是临时数据库的调用问题。
我会把相关代码和报错截图放上来让大家帮我看看。

这个是我的test_watchlist的部分代码(可只看setUp和login和test_login和test_index_page这四个函数)

import unittest
from bs4 import BeautifulSoup
from app import app, db, Movie, User, forge, admin, initdb

class test_watchlist(unittest.TestCase):
def setUp(self):
app.config.update(
TESTING=True,
SQLALCHEMY_DATABASE_URI=‘sqlite:///:memory:’
)
db.create_all()
user=User(name=‘Test’, username=‘test’)
user.set_password(‘1234’)
movie=Movie(title=‘test movie’, year=‘2019’)
#db.session.add_all([user,movie])
db.session.add(user)
db.session.add(movie)

	db.session.commit()
	
	self.client=app.test_client()
	self.runner=app.test_cli_runner()
	
def teardown(self):
	db.session.remove()
	db.drop_all()
	
def login(self):
	self.client.post('/login', data=dict(
		username='test', 
		password='1234'
	),follow_redirects=True)

def test_app_exist(self):
	self.assertIsNotNone(app)
	
def test_app_is_testing(self):
	self.assertTrue(app.config['TESTING'])
	

	
def test_index_page(self):
	
	response=self.client.get('/')
	data = response.get_data(as_text=True)
	self.assertIn("Test's Watchlist",data)
	#self.assertIn('test movie', data)
	self.assertEqual(response.status_code, 200)
						

def test_login(self):
	response=self.client.post('/login', data=dict(
		username='test',
		password='1234'),follow_redirects=True)
	data=response.get_data(as_text=True)
	self.assertIn('login yep', data)
	self.assertIn('logout', data)
	self.assertIn('seting', data)
	
	response=self.client.post('/login', data=dict(
		username='test',
		password='11111'),follow_redirects=True)
	data=response.get_data(as_text=True)
	self.assertIn('error username or password', data)
	
	response=self.client.post('/login', data=dict(
		username='wrong',
		password='1234'),follow_redirects=True)
	data=response.get_data(as_text=True)
	self.assertIn('error username or password', data)
	
	response=self.client.post('/login', data=dict(
		username='',
		password='1234'),follow_redirects=True)
	data=response.get_data(as_text=True)
	self.assertIn('error username or password', data)
	
	response=self.client.post('/login', data=dict(
		username='test',
		password=''),follow_redirects=True)
	data=response.get_data(as_text=True)
	self.assertIn('error username or password', data)

if name==‘main’:
unittest.main()


可看到红线处的报错都和login(登陆)有关。



从这两个图我推测是数据库调用问题。第一个图的报错可看出,主页面会生成xxx’s watchlist这个标题,临时数据库的name是Test,但是黄线处可看出实际的name是admin(是本地数据库的第一个用户)
第二个图是生成xxx’s watchlist标题的基模板代码。

已经排查过很多次,很多地方,改正过一些小错误,但问题依旧无法解决,也直接用作者的github代码运行过,作者的test_watchlist.py也是这么报错。希望大家能给我些建议。


对代码格式的上传方式还不熟,开头的代码格式显示的有问题,放个截图,setUp函数的代码。

纯代码文本或命令行输出建议使用代码块格式化,请不要使用图片上传。

插入代码块的方式:除了将所有代码缩进四格,更方便的插入代码块方式是使用三个连续的反引号作为开始和结束标记,比如:

```
def hello():
    return ‘Hello World’
```

会被渲染为:

 def hello():
     return 'Hello World'

具体请看置顶帖子 技术提问帖发帖规则(创建提问帖前必读)


帖子发布前可以预览的。

代码语法上是没问题,但是配置顺序有问题。我拿albumy项目举例

class BaseTestCase(unittest.TestCase):

    def setUp(self):
        app = create_app('testing')
        self.context = app.test_request_context()
        self.context.push()
        self.client = app.test_client()
        self.runner = app.test_cli_runner()

        db.create_all()

你看,测试工程开头第一行是app = create_app('testing'),创建一个Flask应用示例。

而你是直接导入然后再修改配置

from app import app

app.config.update(
TESTING=True,
SQLALCHEMY_DATABASE_URI=‘sqlite:///:memory:’
)

你是修改了配置,但是!!!

def create_app(config_name=None):
    if config_name is None:
        config_name = os.getenv('FLASK_CONFIG', 'development')

    app = Flask('albumy')

    # 从settings获取配置信息,加载到app.config里
    app.config.from_object(config[config_name])

    # 注册各种模块
    register_extensions(app)
    register_blueprints(app)
    register_commands(app)
    register_errorhandlers(app)
    register_shell_context(app)
    register_template_context(app)

    return app

后面那些注册的模块还都是用修改前的配置啊!

你不要app = create_app('testing')创建完Flask应用后,又去手动修改app.config配置,配置永远放在其他代码前面。

1 个赞

把跑unittest的db config放到起db实例之前, 用是否正在跑unittest来区别:

# DB
if 'unittest' in sys.modules.keys():
    app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:'
else:
    app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////' + os.path.join(app.root_path, 'data.db')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False  # 关闭对模型修改的监控
db = SQLAlchemy(app)  # 初始化扩展,传入程序实例 app