给强制戒毒的人写信要怎么如何才能确保安全收到信

404 - 找不到文件或目录。
404 - 找不到文件或目录。
您要查找的资源可能已被删除,已更改名称或者暂时不可用。Testing Flask Applications — Flask Documentation (0.10)
Testing Flask Applications
Something that is untested is broken.
The origin of this quote is unknown and while it is not entirely correct, it is also
not far from the truth.
Untested applications make it hard to
improve existing code and developers of untested applications tend to
become pretty paranoid.
If an application has automated tests, you can
safely make changes and instantly know if anything breaks.
Flask provides a way to test your application by exposing the Werkzeug
and handling the context locals for you.
You can then use that with your favourite testing solution.
In this documentation
we will use the
package that comes pre-installed with Python.
The Application
First, we need an we will use the application from
If you don’t have that application yet, get the
sources from .
The Testing Skeleton
In order to test the application, we add a second module
(flaskr_tests.py) and create a unittest skeleton there:
import flaskr
import unittest
import tempfile
class FlaskrTestCase(unittest.TestCase):
def setUp(self):
self.db_fd, flaskr.app.config['DATABASE'] = tempfile.mkstemp()
flaskr.app.config['TESTING'] = True
self.app = flaskr.app.test_client()
flaskr.init_db()
def tearDown(self):
os.close(self.db_fd)
os.unlink(flaskr.app.config['DATABASE'])
if __name__ == '__main__':
unittest.main()
The code in the
method creates a new test
client and initializes a new database.
This function is called before
each individual test function is run.
To delete the database after the
test, we close the file and remove it from the filesystem in the
Additionally during setup the
TESTING config flag is activated.
What it does is disabling the error
catching during request handling so that you get better error reports when
performing test requests against the application.
This test client will give us a simple interface to the application.
trigger test requests to the application, and the client will also keep track
of cookies for us.
Because SQLite3 is filesystem-based we can easily use the tempfile module
to create a temporary database and initialize it.
function does two things for us: it returns a
low-level file handle and a random file name, the latter we use as
database name.
We just have to keep the db_fd around so that we can use
function to close the file.
If we now run the test suite, we should see the following output:
$ python flaskr_tests.py
----------------------------------------------------------------------
Ran 0 tests in 0.000s
Even though it did not run any actual tests, we already know that our flaskr
application is syntactically valid, otherwise the import would have died
with an exception.
The First Test
Now it’s time to start testing the functionality of the application.
Let’s check that the application shows “No entries here so far” if we
access the root of the application (/). To do this, we add a new
test method to our class, like this:
class FlaskrTestCase(unittest.TestCase):
def setUp(self):
self.db_fd, flaskr.app.config['DATABASE'] = tempfile.mkstemp()
self.app = flaskr.app.test_client()
flaskr.init_db()
def tearDown(self):
os.close(self.db_fd)
os.unlink(flaskr.app.config['DATABASE'])
def test_empty_db(self):
rv = self.app.get('/')
assert 'No entries here so far' in rv.data
Notice that our test functions begin with the word test; this allows
to automatically identify the method as a test to run.
By using self.app.get we can send an HTTP GET request to the application with
the given path.
The return value will be a
We can now use the
attribute to inspect
the return value (as string) from the application.
In this case, we ensure that
'No entries here so far' is part of the output.
Run it again and you should see one passing test:
$ python flaskr_tests.py
----------------------------------------------------------------------
Ran 1 test in 0.034s
Logging In and Out
The majority of the functionality of our application is only available for
the administrative user, so we need a way to log our test client in and out
of the application.
To do this, we fire some requests to the login and logout
pages with the required form data (username and password).
And because the
login and logout pages redirect, we tell the client to follow_redirects.
Add the following two methods to your FlaskrTestCase class:
def login(self, username, password):
return self.app.post('/login', data=dict(
username=username,
password=password
), follow_redirects=True)
def logout(self):
return self.app.get('/logout', follow_redirects=True)
Now we can easily test that logging in and out works and that it fails with
invalid credentials.
Add this new test to the class:
def test_login_logout(self):
rv = self.login('admin', 'default')
assert 'You were logged in' in rv.data
rv = self.logout()
assert 'You were logged out' in rv.data
rv = self.login('adminx', 'default')
assert 'Invalid username' in rv.data
rv = self.login('admin', 'defaultx')
assert 'Invalid password' in rv.data
Test Adding Messages
We should also test that adding messages works.
Add a new test method
like this:
def test_messages(self):
self.login('admin', 'default')
rv = self.app.post('/add', data=dict(
title='&Hello&',
text='&strong&HTML&/strong& allowed here'
), follow_redirects=True)
assert 'No entries here so far' not in rv.data
assert '&Hello&' in rv.data
assert '&strong&HTML&/strong& allowed here' in rv.data
Here we check that HTML is allowed in the text but not in the title,
which is the intended behavior.
Running that should now give us three passing tests:
$ python flaskr_tests.py
----------------------------------------------------------------------
Ran 3 tests in 0.332s
For more complex tests with headers and status codes, check out the
from the sources which contains a larger test
Other Testing Tricks
Besides using the test client as shown above, there is also the
method that can be used
in combination with the with statement to activate a request context
temporarily.
With this you can access the ,
objects like in view
functions.
Here is a full example that demonstrates this approach:
app = flask.Flask(__name__)
with app.test_request_context('/?name=Peter'):
assert flask.request.path == '/'
assert flask.request.args['name'] == 'Peter'
All the other objects that are context bound can be used in the same
If you want to test your application with different configurations and
there does not seem to be a good way to do that, consider switching to
application factories (see ).
Note however that if you are using a test request context, the
functions are not automatically called
functions.
functions are indeed executed when
the test request context leaves the with block.
If you do want the
functions to be called as well, you
need to call
app = flask.Flask(__name__)
with app.test_request_context('/?name=Peter'):
app.preprocess_request()
This can be necessary to open database connections or something similar
depending on how your application was designed.
If you want to call the
functions you
need to call into
which however
requires that you pass it a response object:
app = flask.Flask(__name__)
with app.test_request_context('/?name=Peter'):
resp = Response('...')
resp = app.process_response(resp)
This in general is less useful because at that point you can directly
start using the test client.
Faking Resources and Context
New in version 0.10.
A very common pattern is to store user authorization information and
database connections on the application context or the
The general pattern for this is to put the object on there on
first usage and then to remove it on a teardown.
Imagine for instance
this code to get the current user:
def get_user():
user = getattr(g, 'user', None)
if user is None:
user = fetch_current_user_from_database()
g.user = user
return user
For a test it would be nice to override this user from the outside without
having to change some code.
This can trivially be accomplished with
hooking the
from contextlib import contextmanager
from flask import appcontext_pushed
@contextmanager
def user_set(app, user):
def handler(sender, **kwargs):
g.user = user
with appcontext_pushed.connected_to(handler, app):
And then to use it:
from flask import json, jsonify
@app.route('/users/me')
def users_me():
return jsonify(username=g.user.username)
with user_set(app, my_user):
with app.test_client() as c:
resp = c.get('/users/me')
data = json.loads(resp.data)
self.assert_equal(data['username'], my_user.username)
Keeping the Context Around
New in version 0.4.
Sometimes it is helpful to trigger a regular request but still keep the
context around for a little longer so that additional introspection can
With Flask 0.4 this is possible by using the
with a with block:
app = flask.Flask(__name__)
with app.test_client() as c:
rv = c.get('/?tequila=42')
assert request.args['tequila'] == '42'
If you were to use just the
the with block, the assert would fail with an error because request
is no longer available (because you are trying to use it outside of the actual request).
Accessing and Modifying Sessions
New in version 0.8.
Sometimes it can be very helpful to access or modify the sessions from the
test client.
Generally there are two ways for this.
If you just want to
ensure that a session has certain keys set to certain values you can just
keep the context around and access :
with app.test_client() as c:
rv = c.get('/')
assert flask.session['foo'] == 42
This however does not make it possible to also modify the session or to
access the session before a request was fired.
Starting with Flask 0.8 we
provide a so called “session transaction” which simulates the appropriate
calls to open a session in the context of the test client and to modify
At the end of the transaction the session is stored.
This works
independently of the session backend used:
with app.test_client() as c:
with c.session_transaction() as sess:
sess['a_key'] = 'a value'
# once this is reached the session was stored
Note that in this case you have to use the sess object instead of the
The object however itself will provide the
same interface.
Related Topics通过配置文件 读取参数进行
时间: 18:05:51
&&&& 阅读:12
&&&& 评论:
&&&& 收藏:0
标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&&
#-*-coding:utf-8-*-
#测试用例配置参数
#XXXXX_Uitest-&baseinfo-&__init__.py
base_url = ""
undirect_username = "XXXX"
undirect_password = "XXXXX"
direct_username = XXXXX"
direct_password = "xxxxxx"
#发送邮件配置参数
Smtp_Server = ‘‘
Smtp_Sender = ‘‘
Smtp_Sender_Password = ‘XXXXXXX‘
Smtp_Receiver = [‘‘,‘‘]
#测试用例及报告路径配置参数
test_dir = ‘./test_case‘
test_report = ‘./test_report/‘
#测试用例,测试代码#test_cart.py
import unittest
import time
from selenium import webdriver
from mon.keys import Keys
class TestCart(unittest.TestCase):
def setUp(self):
print(‘setup‘)
self.url = ‘http://www.XXX.mm‘
self.driver = webdriver.Firefox()
self.driver.implicitly_wait(5)
self.driver.get(self.url)
self.driver.maximize_window()
print("open browser")
#return self.driver
def get_Info(self):
filePath = os.path.join(os.getcwd(),‘user_info‘)
filename = filePath + ‘\\user_info.txt‘
print(filename)
fo = open(filename, ‘r‘)
lines = fo.readlines()
for data in lines:
name,pwd = data.split(‘,‘)
print(name, pwd)
return name,pwd
def test_to_login(self):
‘‘‘验证是否登陆‘‘‘
name,pwd = self.get_Info()
time.sleep(5)
print(name,pwd)
self.driver.implicitly_wait(5)
self.driver.find_element_by_id(‘new-username‘).clear()
self.driver.find_element_by_id(‘new-username‘).send_keys(name)
self.driver.find_element_by_id(‘new-password‘).clear()
self.driver.find_element_by_id(‘new-password‘).send_keys(pwd)
self.driver.implicitly_wait(5)
#回车登陆,因为登陆按钮不好定位
self.driver.find_element_by_xpath("html/body/div[9]/div[3]/div[1]/div[1]/div[4]/span").send_keys(Keys.ENTER)
self.driver.implicitly_wait(10)
login_test = self.driver.find_element_by_xpath(".//*[@id=‘loginOut‘]").text
self.assertEqual(login_test, ‘[退出]‘)
def tearDown(self):
print("tearDown")
time.sleep(5)
print("close browser")
self.driver.quit()
if __name__ == ‘__main__‘:
unittest.main()
#runtest.py
import smtplib
import unittest
import time
import xlrd
from HTMLTestRunner import HTMLTestRunner
from email.header import Header
from email.mime.text import MIMEText#导入baseinfo
import baseinfo
from email.mime.multipart import MIMEMultipart
def get_sender():
filePath =
os.path.join(os.getcwd(),‘user_info‘)
print("get_sender")
print(filePath)
fileName = filePath + ‘\Mail_info.xlsx‘
print(fileName)
readExcel = xlrd.open_workbook(fileName)
sender = readExcel.sheet_by_name(‘sender‘)
get_sender = sender.row_values(1)
#print(get_sender)
return get_sender
def get_Receiver():
filePath =
os.path.join(os.getcwd(),‘user_info‘)
fileName = filePath + ‘\Mail_info.xlsx‘
print("get_Receiver()")
print(fileName)
readExcel = xlrd.open_workbook(fileName)
receiver_sheet = readExcel.sheet_by_name(‘receiver‘)
receiver_temp = receiver_sheet.col_values(0)
getReceiver = receiver_temp[1:]
print(getReceiver)
print(type(getReceiver))
return getReceiver
def get_NewReport(testreport):
dirs = os.listdir(testreport)
dirs.sort()
newreportname = dirs[-1]
print(‘The new report name: {0}‘.format(newreportname))
file_new = os.path.join(testreport, newreportname)
print(file_new)
return file_new
def send_Mail(file_new):
f = open(file_new, ‘rb‘)
# 读取测试报告正文
mail_body = f.read()
     #通过 baseinfo 引用 __init__ 初始化的参数值
smtp = smtplib.SMTP(baseinfo.Smtp_Server, 25)
sender = baseinfo.Smtp_Sender
password = baseinfo.Smtp_Sender_Password
receiver = baseinfo.Smtp_Receiver
smtp.login(sender, password)
msg = MIMEMultipart()
# 编写html类型的邮件正文,MIMEtext()用于定义邮件正文
# 发送正文
text = MIMEText(mail_body, ‘html‘, ‘utf-8‘)
text[‘Subject‘] = Header(‘自动化测试报告‘, ‘utf-8‘)
msg.attach(text)
# 发送附件
# Header()用于定义邮件标题
msg[‘Subject‘] = Header(‘自动化测试报告‘, ‘utf-8‘)
msg_file = MIMEText(mail_body, ‘html‘, ‘utf-8‘)
msg_file[‘Content-Type‘] = ‘application/octet-stream‘
msg_file["Content-Disposition"] = ‘ filename="TestReport.html"‘
msg.attach(msg_file)
#定义发件人,如果不写,发件人为空
msg[‘From‘] = sender
#定义收件人,如果不写,收件人为空
msg[‘To‘] = ",".join(receiver)
tmp = smtp.sendmail(sender, receiver, msg.as_string())
print(receiver)
print(tmp)
smtp.quit()
return True
except smtplib.SMTPException as e:
print(str(e))
return False
if __name__ == ‘__main__‘:
test_dir = os.path.join(os.getcwd(),‘test_case‘)
print(test_dir)
report_dir = os.path.join(os.getcwd(),‘report‘)
test_discover = unittest.defaultTestLoader.discover(test_dir,pattern=‘test*.py‘)
print("test_discover")
now = time.strftime("%Y-%m-%d-%H_%M_%S")
filename = report_dir+‘/result-‘+now+‘.html‘
fp = open(filename, ‘wb‘)
runner = HTMLTestRunner(stream = fp, title = ‘UI自动化测试报告‘, description = ‘用例执行情况‘)
#runner = unittest.TextTestRunner()
runner.run(test_discover)
fp.close()
new_report = get_NewReport(report_dir)
mail = send_Mail(new_report)
print("发送成功!")
print("发送失败!")
&标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&原文:/Skyyj/p/6763529.html
教程昨日排行
&&国之画&&&& &&&&&&
&& &&&&&&&&&&&&&&
鲁ICP备号-4
打开技术之扣,分享程序人生!单元测试系列之4:使用Unitils测试DAO层 - stamen的程序员之路 - ITeye技术网站
博客分类:
&& Spring 的测试框架为我们提供一个强大的测试环境,解决日常单元测试中遇到的大部分测试难题:如运行多个测试用例和测试方法时,Spring上下文只需创建一次;数据库现场不受破坏;方便手工指定Spring配置文件、手工设定Spring容器是否需要重新加载等。但也存在不足的地方,基本上所有的Java应用都涉及数据库,带数据库应用系统的测试难点在于数据库测试数据的准备、维护、验证及清理。Spring 测试框架并不能很好地解决所有问题。要解决这些问题,必须整合多方资源,如DbUnit、Unitils、Mokito等。其中Unitils正是这样的一个测试框架。
数据库测试的难点
&&& 按照Kent Back的观点,单元测试最重要的特性之一应该是可重复性。不可重复的单元测试是没有价值的。因此好的单元测试应该具备独立性和可重复性,对于业务逻辑层,可以通过Mockito底层对象和上层对象来获得这种独立性和可重复性。而DAO层因为是和数据库打交道的层,其单元测试依赖于数据库中的数据。要实现DAO层单元测试的可重复性就需要对每次因单元测试引起数据库中的数据变化进行还原,也就是保护单元测试数据库的数据现场。
扩展Dbunit用Excel准备数据
&&& 在测试数据访问层(DAO)时,通常需要经过测试数据的准备、维护、验证及清理的过程。这个过程不仅烦锁,而且容易出错,如数据库现场容易遭受破坏、如何对数据操作正确性进行检查等。虽然Spring测试框架在这一方面为我们减轻了很多工作,如通过事务回滚机制来保存数据库现场等,但对测试数据及验证数据准备方面还没有一种很好的处理方式。Unitils框架出现,改变了难测试DAO的局面,它将SpringModule、DatabaseModule、DbUnitModule等整合在一起,使得DAO的单元测试变得非常容易。基于Unitils框架的DAO测试过程如图16-6所示。
&& 以JUnit作为整个测试的基础框架,并采用DbUnit作为自动管理数据库的工具,以XML、Excel作为测试数据及验证数据准备,最后通过Unitils的数据集注解从Excel、XML文件中加载测试数据。使用一个注解标签就可以完成加载、删除数据操作。由于XML作为数据集易用性不如Excel,在这里就不对XML数据集进行讲解。下面我们主要讲解如何应用Excel作为准备及验证数据的载体,减化DAO单元测试。由于Unitils没有提供访问Excel的数据集工厂,因此需要编写插件支持Excel格式数据源。Unitils提供一个访问XML的数据集工厂MultiSchemaXmlDataSetFactory,其继承自DbUnit提供的数据集工厂接口DataSetFactory。我们可以参考这个XML数据集工厂类,编写一个访问Excel的数据集工厂MultiSchemaXlsDataSetFactory及Excel数据集读取器MultiSchemaXlsDataSetReader,然后在数据集读取器中调用Apache POI类库来读写Excel文件。如代码清单16-20所示。
import org.unitils.core.UnitilsE
import org.unitils.DbUnit.datasetfactory.DataSetF
import org.unitils.DbUnit.util.MultiSchemaDataS
public class MultiSchemaXlsDataSetFactory implements DataSetFactory {
protected String defaultSchemaN
//① 初始化数据集工厂
public void init(Properties configuration, String defaultSchemaName) {
this.defaultSchemaName = defaultSchemaN
//② 从Excel文件创建数据集
public MultiSchemaDataSet createDataSet(File... dataSetFiles) {
MultiSchemaXlsDataSetReader xlsDataSetReader =
new MultiSchemaXlsDataSetReader(defaultSchemaName);
return xlsDataSetReader.readDataSetXls(dataSetFiles);
} catch (Exception e) {
throw new UnitilsException("创建数据集失败: "
+ Arrays.toString(dataSetFiles), e);
获取数据集文件的扩展名
public String getDataSetFileExtension() {
return "xls";
&& 与XML数据集工厂MultiSchemaXmlDataSetFactory一样,Excel的数据集工厂也需要实现数据集工厂接口DataSetFactory的三个方法:init(…)、createDataSet(File... dataSetFiles)、getDataSetFileExtension()。在①处,初始化数据集工厂,需要设置一个默认的数据库表模式名称defaultSchemaName。在②处,执行创建多数据集,具体读取构建数据集的过程封装在Excel读取器MultiSchemaXlsDataSetReader中。在③处,获取数据集文件的扩展名,对Excel文件而言就是“xls”。下面来看一下这个数据集读取器的实现代码。
import org.unitils.core.UnitilsE
import org.unitils.DbUnit.datasetfactory.DataSetF
import org.unitils.DbUnit.util.MultiSchemaDataS
// Excel数据集读取器
public class MultiSchemaXlsDataSetReader {
private String defaultSchemaN
public MultiSchemaXlsDataSetReader(String defaultSchemaName) {
this.defaultSchemaName = defaultSchemaN
// Excel数据集读取器
public MultiSchemaDataSet readDataSetXls(File... dataSetFiles) {
Map&String, List&ITable&& tableMap = getTables(dataSetFiles);
MultiSchemaDataSet dataSets = new MultiSchemaDataSet();
for (Entry&String, List&ITable&& entry : tableMap.entrySet()) {
List&ITable& tables = entry.getValue();
DefaultDataSet ds = new DefaultDataSet(tables
.toArray(new ITable[] {}));
dataSets.setDataSetForSchema(entry.getKey(), ds);
} catch (AmbiguousTableNameException e) {
throw new UnitilsException("构造DataSet失败!",
return dataS
} catch (Exception e) {
throw new UnitilsException("解析EXCEL文件出错:", e);
  根据传入的多个Excel文件,构造一个多数据集。 其中一个数据集对应一个Excel文件,一个Excel的Sheet表对应一个数据库Table。通过DbUnit提供Excel数据集构造类XlsDataSet,可以很容易将一个Excel文件转换为一个数据集:XlsDataSet(new FileInputStream(xlsFile))。最后将得到的多个DataSet用MultiSchemaDataSet进行封装。
  下面就以一个用户DAO的实现类WithoutSpringUserDaoImpl为例,介绍如何使用我们实现的Excel数据集工厂。为了让Unitils使用自定义的数据集工厂,需要在unitils.properties配置文件中指定自定义的数据集工厂。
引用…
DbUnitModule.DataSet.factory.default=sample.unitils.dataset.excel.MultiSchemaXlsDataSetFactory
DbUnitModule.ExpectedDataSet.factory.default=sample.unitils.dataset.excel.MultiSchemaXlsDataSetFactory
  其中DbUnitModule.DataSet.factory.default是配置数据集工厂类,在测试方法中可以使用@DataSet注解加载指定的准备数据。默认是XML数据集工厂,这里指定自定义数据集工厂类全限定名为  sample.unitils.dataset.excel.MultiSchemaXlsDataSetFactory。
  其中DbUnitModule. ExpectedDataSet.factory.default是配置验证数据集工厂类,也是指定自定义数据集工厂类,使用@ ExpectedDataSet注解加载验证数据。
import org.unitils.core.UnitilsE
import org.unitils.DbUnit.datasetfactory.DataSetF
import org.unitils.DbUnit.util.MultiSchemaDataS
public class UserDaoTest extends UnitilsJUnit4 {
@DataSet //① 准备测试数据
public void getUser() {
@DataSet("BaobaoTao.SaveUser.xls") //② 准备测试数据 -
@ExpectedDataSet //③ 准备验证数据
public void saveUser()throws Exception
  @DateSet 注解表示了测试时需要寻找DbUnit的数据集文件进行加载,如果没有指明数据集的文件名,则Unitils自动在当前测试用例所在类路径下加载文件名为测试用例类名的数据集文件,实例中①处,将到UserDaoTest.class所在目录加载WithExcelUserDaoTest.xls 数据集文件。
  @ExpectedDataSet注解用于加载验证数据集文件,如果没有指明数据集的文件名,则会在当前测试用例所在类路径下加载文件名为testClassName.methodName-result.xls的数据集文件。实例中③处将加载UserDaoTest. saveUser.result.xls数据集文件。
  使用JUnit作为基础测试框架,结合Unitils、DbUnit管理测试数据,并使用我们编写的Excel数据集工厂(见代码清单16 20)。从Excel数据集文件中获取准备数据及验证数据,并使用HSQLDB作为测试数据库。下面详细介绍如何应用Excel准备数据集及验证数据集来测试DAO。
  在进行DAO层的测试之前,我们先来认识一下需要测试的UserDaoImpl用户数据访问类。UserDaoImpl用户数据访问类中拥有一个获取用户信息和保存注册用户信息的方法,其代码如下所示。
import java.util.L
import org.hibernate.S
import org.hibernate.SessionF
import org.springframework.orm.hibernate3.HibernateT
import com.baobaotao.dao.UserD
import com.baobaotao.domain.U
public class UserDaoImpl implements UserDao {
//通过用户名获取用户信息
public User findUserByUserName(String userName) {
String hql = " from User u where u.userName=?";
List&User& users = getHibernateTemplate().find(hql, userName);
if (users != null && users.size() & 0)
return users.get(0);
//保存用户信息
public void save(User user) {
getHibernateTemplate().saveOrUpdate(user);
  我们认识了需要测试的UserDaoImpl用户数据访问类之后,还需要认识一下用于表示用户领域的对象User,在演示测试保存用户信息及获取用户信息时需要用到此领域对象,其代码如下所示。
import javax.persistence.C
import javax.persistence.E
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Table(name = "t_user")
public class User implements Serializable{
@Column(name = "user_id")
protected int userId;
@Column(name = "user_name")
protected String userN
protected S
@Column(name = "last_visit")
protected Date lastV
@Column(name = "last_ip")
protected String lastIp;
@Column(name = "credits")
  用户登录日志领域对象LoginLog与用户领域对象Hibernate注解配置一致,这里就不再列出,读者可以参考本书附带光盘中的实例代码。在实例测试中,我们直接使用Hibernate进行持久化操作,所以还需要对Hibernate进行相应配置,详细的配置清单如下所示。
&?xml version="1.0" encoding="UTF-8"?&
&!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"&
&hibernate-configuration&
&session-factory&
SQL方言,这边设定的是HSQL --&
&property name="dialect"&org.hibernate.dialect.HSQLDialect&/property&
&!--② 数据库连接配置 --&
&property name="hibernate.connection.driver_class"&org.hsqldb.jdbcDriver&/property&
&property name="hibernate.connection.url"&
jdbc:hsqldb:data/sampledb
&/property&
&!--设置连接数据库的用户名--&
&property name="hibernate.connection.username"&sa&/property&
&!--设置连接数据库的密码--&
&property name="hibernate.connection.password"&&/property&
&!--③ 设置显示sql语句方便调试--&
&property name="hibernate.show_sql"&true&/property&
配置映射 --&
&property name="configurationClass"&
org.hibernate.cfg.AnnotationConfiguration
&/property&
&mapping class="com.baobaotao.domain.User" /&
&mapping class="com.baobaotao.domain.LoginLog" /&
&/session-factory&
&/hibernate-configuration&
& 选用HSQLDB作为测试数据库,在①处,配置HSQLDB的SQL方言HSQLDialect。在②处,对连接数据库驱动及数据库连接进行相应的配置。为了方便测试调试,在③处设置显示Hibernate生成的SQL语句。在④处启用Hibernate的注解功能,并配置相应的领域对象,如实例中的User、LoginLog。将配置好的hibernate.cfg.xml放在src目录下。
配置Unitils测试环境
& 要在单元测试中更好地使用Unitils ,首先需要在测试源码的根目录中创建一个项目级unitils.properties 配置文件,实例中unitils.properties详细配置清单如下所示。
#① 启用unitils所需模块
unitils.modules=database,dbunit,hibernate,spring
#自定义扩展模块,详见实例源码
unitils.module.dbunit.className=sample.unitils.module.CustomExtModule
#② 配置数据库连接
database.driverClassName=org.hsqldb.jdbcDriver
database.url=jdbc:hsqldb:data/shutdown=true
database.userName=sa
database.password=
database.schemaNames=public
database.dialect = hsqldb
#③ 配置数据库维护策略.
updateDataBaseSchema.enabled=true
#④ 配置数据库表创建策略
dbMaintainer.autoCreateExecutedScriptsTable=true
dbMaintainer.script.locations=D:/masterSpring/chapter16/resources/dbscripts
#⑤ 数据集加载策略
#DbUnitModule.DataSet.loadStrategy.default=org.unitils.dbunit.datasetloadstrategy.InsertLoadStrategy
#⑥ 配置数据集工厂
DbUnitModule.DataSet.factory.default=sample.unitils.dataset.excel.MultiSchemaXlsDataSetFactory
DbUnitModule.ExpectedDataSet.factory.default=sample.unitils.dataset.excel.MultiSchemaXlsDataSetFactory
#⑦ 配置事务策略
DatabaseModule.Transactional.value.default=commit
#⑧ 配置数据集结构模式XSD生成路径
dataSetStructureGenerator.xsd.dirName=resources/xsd
&& 我们知道unitils.properties中配置的属性是整个项目级别的,整个项目都可以使用这些全局的属性配置。特定用户使用的属性可以设置在unitils-local.properties 文件中,比如user、password和schema,这样每个开发者就使用自定义的测试数据库的schema,而且彼此之间也不会产生影响,实例的详细配置清单如下所示。
database.userName=sa
database.password=
database.schemaNames=public
&& 如果用户分别在unitils.properties文件及unitils -local.properties文件中对相同属性配置不同值时,将会以unitils-local.properties 配置内容为主。如在unitils.properties配置文件中,也配置了database.schemaNames=xxx,测试时启用的是用户自定义配置中的值database.schemaNames=public。
&& 默认的数据集加载机制采用先清理后插入的策略,也就是数据在被写入数据库的时候是会先删除数据集中有对应表的数据,然后将数据集中的数据写入数据库。这个加载策略是可配置的,我们可以通过修改DbUnitModule.DataSet.loadStrategy.default的属性值来改变加载策略。如实例代码清单16 27中⑤配置策略,这时加载策略就由先清理后插入变成了插入,数据已经存在表中将不会被删除,测试数据只是进行插入操作。可选的加载策略列表如下所示。
?& CleanInsertLoadStrategy:先删除dateSet中有关表的数据,然后再插入数据。
?& InsertLoadStrategy:只插入数据。
?& RefreshLoadStrategy:有同样key的数据更新,没有的插入。
?& UpdateLoadStrategy: 有同样key的数据更新,没有的不做任何操作。
配置事务策略
&& 在测试DAO的时候都会填写一些测试数据,每个测试运行都会修改或者更新了数据,当下一个测试运行的时候,都需要将数据恢复到原有状态。如果使用的是Hibernate或者JPA,需要每个测试都运行在事务中,保证系统的正常工作。默认情况下,事务管理是disabled的,我们可以通过修改DatabaseModule.Transactional.value.default配置选项,如实例代码清单16 27中⑧配置策略,这时每个测试都将执行commit,其他可选的配置属性值有rollback和disabled。
准备测试数据库及测试数据
&& 配置好了Unitils基本配置、加载模块、数据集创建策略、事务策略之后,我们就着手开始测试数据库及测试数据准备工作,首先我们创建测试数据库。
创建测试数据库
&& 在源码包根目录下创建一个dbscripts文件夹(文件夹目录结构如图16-7所示),且这个文件夹必须与在unitils.properties 文件中dbMaintainer.script.locations配置项指定的位置一致,如代码清单16 27中④ 所示。
&& 在这个文件夹中创建一个数据库创建脚本文件001_create_sampledb.sql,里面包含创建用户表t_user 及登录日志表t_login_log,详细的脚本如下所示。
CREATE TABLE t_user (
user_id INT generated by default as identity (start with 100),
user_name VARCHAR(30),credits INT,
VARCHAR(32),last_visit timestamp,
VARCHAR(23), primary key (user_id));
CREATE TABLE t_login_log (
login_log_id
INT generated by default as identity (start with 1),
VARCHAR(23),
login_datetime timestamp,
primary key (login_log_id));
&& 细心的读者可能会发现这个数据库创建脚本文件名好像存在一定的规则,是的,这个脚本文件命名需要按以下规则命名:版本号 +& “_” +& “自定义名称” + “ .sql” 。
连接到测试数据库
&& 测试DAO时,读者要有个疑问,测试数据库用到的数据源来自哪里,怎么让我们测试的DAO类来使用我们的数据源。执行测试实例的时候,Unitils 会根据我们定义的数据库连接属性来创建一个数据源实例连接到测试数据库。随后的DAO测试会重用相同的数据源实例。建立连接的细节定义在unitils.properties配置文件中,如代码清单16 27中的② 配置部分所示。
用Excel准备测试数据
&& 准备好测试数据库之后,剩下的工作就是用Excel来准备测试数据及验证数据,回顾一下我们要测试的UserDaoImpl 类(代码清单16 24),需要对其中的获取用户信息方法findUserByUserName()及保存用户信息方法saveUser()进行测试,所以我们至少需要准备三个Excel数据集文件 ,分别是供查询用户用的数据集BaobaoTao.Users.xls、供保存用户信息用的数据集BaobaoTao.SaveUser.xls及供保存用户信息用的验证数据集BaobaoTao. ExpectedSaveUser.xls。下面以用户数据集BaobaoTao.Users.xls实例进行说明,如图16-8所示。
&& 在①处t_user表示数据库对应的表名称。在②处表示数据库中t_user表对应的字段名称。在③处表示准备测试的模拟数据。一个数据集文件可以对应多张表,一个Sheet对就一张表。把创建好的数据集文件放到与测试类相同的目录中,如实例中的UserDaoTest类位于com.baobaotao.dao包中,则数据集文件需要放到当前包中。其他两个数据集文件数据结构如图16-9和16-10所示。
编写UserDaoImpl的测试用例
& 完成了Unitils环境配置、准备测试数据库及测试数据之后,就可以开始编写用户DAO单元测试类,下面我们为用户数据访问UserDaoImpl编写测试用例类。
import org.unitils.core.UnitilsE
import org.unitils.DbUnit.datasetfactory.DataSetF
import org.unitils.DbUnit.util.MultiSchemaDataS
@SpringApplicationContext( {"baobaotao-dao.xml" }) //① 初始化Spring容器
public class UserDaoTest extends UnitilsJUnit4 {
@SpringBean("jdbcUserDao")
//② 从Spring容器中加载DAO
private UserDao userD
public void init() {
&& 在①处,通过Unitils提供@ SpringApplicationContext注解加载Spring配置文件,并初始化Spring容器。在②处,通过@SpringBean注解从Spring容器加载一个用户DAO实例。编写UserDaoTest测试基础模型之后,接下来就编写查询用户信息findUserByUserName()的测试方法。
代码清单16 31 UserDaoTest.findUserByUserName()测试
import org.unitils.core.UnitilsE
import org.unitils.DbUnit.datasetfactory.DataSetF
import org.unitils.DbUnit.util.MultiSchemaDataS
public class UserDaoTest extends UnitilsJUnit4 {
@Test //① 标志为测试方法
@DataSet("BaobaoTao.Users.xls") //② 加载准备用户测试数据
public void findUserByUserName() {
User user = userDao.findUserByUserName("tony"); //③ 从数据库中加载tony用户
assertNull("不存在用户名为tony的用户!", user);
user = userDao.findUserByUserName("jan"); //④ 从数据库中加载jan用户
assertNotNull("jan用户存在!", user);
assertEquals("jan", user.getUserName());
assertEquals("123456",user.getPassword());
assertEquals(10,user.getCredits());
&& 在①处,通过JUnit提供@Test注解,把当前方法标志为可测试方法。在②处,通过Unitils提供的@DataSet注解从当前测试类UserDaoTest.class所在的目录寻找支持DbUnit的数据集文件并进行加载。执行测试逻辑之前,会把加载的数据集先持久化到测试数据库中,具体加载数据集的策略详见上文“配置数据集加载策略”部分。实例中采用的默认加载策略,即先删除测试数据库对应表的数据再插入数据集中的测试数据。这种策略可以避免不同测试方法加载数据集相互干扰。在③处执行查询用户方法时,测试数据库中t_user表数据已经是如图16-8 BaobaoTao.Users.xls所示的数据,因此查询不到“tony”用户信息。在④处,执行查询“jan”用户信息,从测试数据集可以看出,可以加载到“jan”的详细信息。最后在IDE中执行UserDaoTest. findUserByUserName()测试方法,按我们预期通过测试,测试结果如图16-11所示。
&& 完成了查询用户的测试之后,我们开始着手编写保存用户信息的测试方法,详细的实现代码如下所示。
import org.unitils.core.UnitilsE
import org.unitils.DbUnit.datasetfactory.DataSetF
import org.unitils.DbUnit.util.MultiSchemaDataS
public class UserDaoTest extends UnitilsJUnit4 {
//① 标志为测试方法
@ExpectedDataSet("BaobaoTao.ExpectedSaveUser.xls") //准备验证数据
public void saveUser()throws Exception
User u = new User();
u.setUserId(1);
u.setUserName("tom");
u.setPassword("123456");
u.setLastVisit(getDate(" 08:00:00","yyyy-MM-dd HH:mm:ss"));
u.setCredits(30);
u.setLastIp("127.0.0.1");
userDao.save(u);
//执行用户信息更新操作
&& 在①处,通过JUnit提供@Test注解,把当前方法标志为可测试方法。在②处,通过Unitils提供的@ExpectedDataSet注解从当前测试类UserDaoTest.class所在的目录寻找支持DbUnit的验证数据集文件并进行加载,之后验证数据集里的数据和数据库中的数据是否一致。在UserDaoTest.saveUser()测试方法中创建一个User实例,并设置与图16-10 验证数据集中相同的数据,然后执行保存用户操作。最后在IDE中执行UserDaoTest.saveUser()测试方法,执行结果如图16-12所示。
&& 虽然已经成功完成了保存用户信息UserDaoTest.saveUser() 方法测试,但还是存在不足的地方,我们测试数据通过硬编码方式直接设置在User实例中。如果需要更改测试数据,只能更改测试代码。大大削减了测试的灵活性。如果能直接从Excel数据集获取测试数据,并自动绑定到目标对象,那我们的测试用例就更加完美。为此笔者编写了一个获取Excel数据集Bean工厂XlsDataSetBeanFactory,用于自动绑定数据集到测试对象。我们对上面的测试方法进行整改,实现代码如代码清单16-33所示。
import org.unitils.core.UnitilsE
import org.unitils.DbUnit.datasetfactory.DataSetF
import org.unitils.DbUnit.util.MultiSchemaDataS
import sample.unitils.dataset.util.XlsDataSetBeanF
public class UserDaoTest extends UnitilsJUnit4 {
//① 标志为测试方法
@ExpectedDataSet("BaobaoTao.ExpectedSaveUser.xls") //准备验证数据
public void saveUser()throws Exception
//② 从保存数据集中创建Bean
= XlsDataSetBeanFactory.createBean("BaobaoTao.SaveUser.xls”
,"t_user", User.class);
userDao.save(u); //③ 执行用户信息更新操作
&& 在②处,通过XlsDataSetBeanFactory.createBean()方法,从当前测试类所在目录加载BaobaoTao.SaveUser.xls数据集文件,其数据结构如图16-9所示。把BaobaoTao.SaveUser.xls中名称为t_user 的Sheet页中的数据绑定到User对象,如果当前Sheet页有多条记录,可以通过XlsDataSetBeanFactory.createBeans()获取用户列表List&User&。最后在IDE中重新执行UserDaoTest.saveUser()测试方法,执行结果如图16-13所示。
&& 从测试结果可以看出,执行UserDaoTest.saveUser()测试失败。从右边的失败报告信息我们可以看出,是由于模拟用户的积分与我们期望数据不一致造成,期望用户积分是30,而我们保存用户的积分是10。重新对比一下图16-9 BaobaoTao.SaveUser.xls数据集数据与图16-10 BaobaoTao.ExpectedSaveUser.xls数据集的数据,确实我们准备保存数据集的数据与验证结果的数据不一致。把BaobaoTao.SaveUser.xls数据集中的用户积分更改为30,最后在IDE中重新执行UserDaoTest.saveUser()测试方法,执行结果如图16-14所示。
&& 从测试结果可以看出,保存用户通过测试。从上述的测试实战,我们已经体验到用Excel准备测试数据与验证数据带来的便捷性。到此,我们完成了DAO测试的整个过程,对于XlsDataSetBeanFactory具体实现,读者可以查看本章的实例源码,这里就不做详细分析。下面是实现基本骨架。
import org.dbunit.dataset.C
import org.dbunit.dataset.DataSetE
import org.dbunit.dataset.IDataS
import org.dbunit.dataset.IT
import org.dbunit.dataset.excel.XlsDataS
public class XlsDataSetBeanFactory {
//从Excel数据集文件创建多个Bean
public static &T& List&T& createBeans(String file, String tableName,
Class&T& clazz) throws Exception {
BeanUtilsBean beanUtils = createBeanUtils();
List&Map&String, Object&& propsList = createProps(file, tableName);
List&T& beans = new ArrayList&T&();
for (Map&String, Object& props : propsList) {
T bean = clazz.newInstance();
beanUtils.populate(bean, props);
beans.add(bean);
//从Excel数据集文件创建多个Bean
public static &T& T createBean(String file, String tableName, Class&T& clazz)
throws Exception {
BeanUtilsBean beanUtils = createBeanUtils();
List&Map&String, Object&& propsList = createProps(file, tableName);
T bean = clazz.newInstance();
beanUtils.populate(bean, propsList.get(0));
浏览 12445
论坛回复 /
(24 / 12691)
##################################### Default configuration of Unitils ##################################### # This file contains default configuration values for unitils. This file should not be edited.# All properties in this file can be overridden, either in the project specific properties file# (unitils.properties) or in the local properties file (configured by unitils.configuration.customFileName). # Name or path of the project specific properties file. The system will try to find this file in the classpath (recommended),# the user home folder or the local filesystemunitils.configuration.customFileName=unitils.properties# Name or path of the user specific properties file. This file may contain the necessary parameters to connect to the# developer's own unit test schema. It is recommended to override the name of this file in the project specific properties# file, to include the name of the project. The system will try to find this file in the classpath, the user home folder# (recommended) or the local filesystem.unitils.configuration.localFileName=unitils-local.properties # List of modules that is loaded. Overloading this list is normally not useful, unless you want to add a custom# module. Disabling a module can be performed by setting unitils.module.&modulename&.enabled to false.# If a module's specific dependencies are not found (e.g. hibernate is not in you classpath), this module is not loaded,# even if it is in this list and the enabled property is set to true. It's therefore not strictly necessary to disable# any of these modules.unitils.modules=database,dbunit,hibernate,mock,easymock,inject,spring,jpa,io #### Unitils core configuration #### For each module, the implementation class is listed in unitils.module.&modulename&.className, the sequence of the# execution of their code is influenced by unitils.module.&modulename&.runAfter. Disabling a module can be performed by# setting unitils.module.&modulename&.enabled to false.unitils.module.database.className=org.unitils.database.DatabaseModuleunitils.module.database.runAfter=unitils.module.database.enabled=true unitils.module.hibernate.className=org.unitils.orm.hibernate.HibernateModuleunitils.module.hibernate.runAfter=unitils.module.hibernate.enabled=true unitils.module.dbunit.className=org.unitils.dbunit.DbUnitModuleunitils.module.dbunit.runAfter=unitils.module.dbunit.enabled=true unitils.module.mock.className=org.unitils.mock.MockModuleunitils.module.mock.runAfter=unitils.module.mock.enabled=true unitils.module.easymock.className=org.unitils.easymock.EasyMockModuleunitils.module.easymock.runAfter=unitils.module.easymock.enabled=true unitils.module.inject.className=org.unitils.inject.InjectModuleunitils.module.inject.runAfter=unitils.module.inject.enabled=true unitils.module.spring.className=org.unitils.spring.SpringModuleunitils.module.spring.runAfter=databaseunitils.module.spring.enabled=true unitils.module.jpa.className=org.unitils.orm.jpa.JpaModuleunitils.module.jpa.runAfter=unitils.module.jpa.enabled=true unitils.module.io.className=org.unitils.io.IOModuleunitils.module.io.runAfter=unitils.module.io.enabled=true
### DatabaseModule Configuration ### ## Full qualified class name of an implementation of org.unitils.database.config.DataSourceFactory. This class is used# to provide a DataSource for all database unit tests and for the DBMaintainer.org.unitils.database.config.DataSourceFactory.implClassName=org.unitils.database.config.PropertiesDataSourceFactory # Properties for the PropertiesDataSourceFactorydatabase.driverClassName=database.url=database.userName=database.password= # This property specifies the underlying DBMS implementation. Supported values are 'oracle', 'db2', 'mysql', 'hsqldb',# 'postgresql', 'derby' and 'mssql'. The value of this property defines which vendor specific implementations of# DbSupport and ConstraintsDisabler are chosen.database.dialect= # A comma-separated list of all used database schemas. The first schema name is the default one, if no schema name is# specified in for example a dbunit data set, this default one is used.# A schema name is case sensitive if it's surrounded by database identifier quotes (e.g. " for oracle)database.schemaNames=
### DatabaseModule's DbMaintainer configuration ### # If set to true, the DBMaintainer will be used to update the unit test database schema. This is done once for each# test run, when creating the DataSource that provides access to the unit test database.updateDataBaseSchema.enabled=false # Indicates the database must be recreated from scratch when an already executed script is updated. If false, the# DBMaintainer will give an error when an existing script is updated.dbMaintainer.fromScratch.enabled=true# Indicates whether a from scratch update should be performed when the previous update failed, but# none of the scripts were modified since that last update. If false a new update will be tried only when# changes were made to the script files.dbMaintainer.keepRetryingAfterError.enabled=false # Fully qualified classnames of implementations of org.unitils.core.dbsupport.DbSupport.org.unitils.core.dbsupport.DbSupport.implClassName.oracle=org.unitils.core.dbsupport.OracleDbSupportorg.unitils.core.dbsupport.DbSupport.implClassName.oracle9=org.unitils.core.dbsupport.Oracle9DbSupportorg.unitils.core.dbsupport.DbSupport.implClassName.oracle10=org.unitils.core.dbsupport.Oracle10DbSupportorg.unitils.core.dbsupport.DbSupport.implClassName.hsqldb=org.unitils.core.dbsupport.HsqldbDbSupportorg.unitils.core.dbsupport.DbSupport.implClassName.mysql=org.unitils.core.dbsupport.MySqlDbSupportorg.unitils.core.dbsupport.DbSupport.implClassName.db2=org.unitils.core.dbsupport.Db2DbSupportorg.unitils.core.dbsupport.DbSupport.implClassName.postgresql=org.unitils.core.dbsupport.PostgreSqlDbSupportorg.unitils.core.dbsupport.DbSupport.implClassName.derby=org.unitils.core.dbsupport.DerbyDbSupportorg.unitils.core.dbsupport.DbSupport.implClassName.mssql=org.unitils.core.dbsupport.MsSqlDbSupport
# Determines how the database stores non-quoted identifiers (with identifiers, we mean names for tables, columns, etc.)# Possible values are lower_case, upper_case, mixed_case and auto# If auto is specified, the database metadata is used to determine the correct valuedatabase.storedIndentifierCase.oracle=autodatabase.storedIndentifierCase.hsqldb=autodatabase.storedIndentifierCase.mysql=autodatabase.storedIndentifierCase.db2=autodatabase.storedIndentifierCase.postgresql=autodatabase.storedIndentifierCase.derby=autodatabase.storedIndentifierCase.mssql=auto # Determines the string the database uses to quote identifiers, i.e. make them case-sensitive# (with identifiers, we mean names for tables, columns, etc.)# Leave empty if quoting is not supported.# If auto is specified, the database metadata is used to determine the correct valuedatabase.identifierQuoteString.oracle=autodatabase.identifierQuoteString.hsqldb=autodatabase.identifierQuoteString.mysql=autodatabase.identifierQuoteString.db2=autodatabase.identifierQuoteString.postgresql=autodatabase.identifierQuoteString.derby=autodatabase.identifierQuoteString.mssql=auto
# Fully qualified name of the implementation of org.unitils.dbmaintainer.maintainer.version.ExecutedScriptInfoSource that is used.# The default value is 'org.unitils.dbmaintainer.maintainer.version.ExecutedScriptInfoSource', which retrieves the database version# from the updated database schema itself. Another implementation could e.g. retrieve the version from a file.org.unitils.dbmaintainer.version.ExecutedScriptInfoSource.implClassName=org.unitils.dbmaintainer.version.impl.DefaultExecutedScriptInfoSource# Name of the table that contains the database update script that have already been executed on the database.dbMaintainer.executedScriptsTableName=dbmaintain_scripts# Name of the column in which the name of the executed script file is storeddbMaintainer.fileNameColumnName=file_namedbMaintainer.fileNameColumnSize=150# Name of the column in which the version index string of the executed script is stored.dbMaintainer.versionColumnName=versiondbMaintainer.versionColumnSize=25# Name of the column in which the last modification date of the executed script file is stored.dbMaintainer.fileLastModifiedAtColumnName=file_last_modified_at# Name of the column in which the checksum of the content of the script is stored.dbMaintainer.checksumColumnName=checksumdbMaintainer.checksumColumnSize=50# Name of the column that stores the timestamp at which the script was executeddbMaintainer.executedAtColumnName=executed_atdbMaintainer.executedAtColumnSize=20# Name of the column in which is stored whether the script ran without error or not.dbMaintainer.succeededColumnName=succeeded# Set this property to true if the dbmaintain_scripts table should be created automatically if not found.# If false, an exception is thrown when the table is not found, indicating how to create it manually.# This property is false by default to be sure that a database is cleared by accident. If an executed# scripts table is available, we assume it to be a database managed by dbmaintain.dbMaintainer.autoCreateExecutedScriptsTable=falsedbMaintainer.timestampFormat=yyyy-MM-dd HH:mm:ss # Fully qualified name of the implementation of org.unitils.dbmaintainer.maintainer.script.ScriptSource that is used.# The default value is 'org.unitils.dbmaintainer.maintainer.script.FileScriptSource', which will retrieve the scripts# from the local file system.org.unitils.dbmaintainer.script.ScriptSource.implClassName=org.unitils.dbmaintainer.script.impl.DefaultScriptSource# Defines where the scripts can be found that must be executed on the database. Multiple locations may be# configured, separated by comma's. A script location can be a folder or a jar file.dbMaintainer.script.locations=# Extension of the files containing the database update scriptsdbMaintainer.script.fileExtensions=sql,ddl# Comma separated list of directories and files in which the post processing database scripts are# located. Directories in this list are recursively search for files.dbMaintainer.postProcessingScript.directoryName=postprocessing # Defines whether script last modification dates can be used to decide that it didn't change. If set to true,# the dbmaintainer will decide that a file didn't change since the last time if it's last modification date hasn't# changed. If it did change, it will first calculate the checksum of the file to verify that the content really# changed. Setting this property to true improves performance: if set to false the checksum of every script must# be calculated for each run of the dbmaintainer. It's advised to set this property to true when using the dbmainainer# to update a unit test database. For applying changes to an environment that can only be updated incrementally (e.g.# a database use by testers or even the production database), this parameter should be false, since working with last# modification dates is not guaranteed to be 100% bulletproof (although unlikely, it is possible that a different# version of the same file is checked out on different systems on exactly the same time).dbMaintainer.useScriptFileLastModificationDates.enabled=true # Fully qualified name of the implementation of org.unitils.dbmaintainer.script.ScriptRunner that is used. The# default value is 'org.unitils.dbmaintainer.script.SQLScriptRunner', which executes a regular SQL script.org.unitils.dbmaintainer.script.ScriptRunner.implClassName=org.unitils.dbmaintainer.script.impl.DefaultScriptRunner# Fully qualified classname of the implementation of org.unitils.dbmaintainer.script.ScriptParserorg.unitils.dbmaintainer.script.ScriptParser.implClassName=org.unitils.dbmaintainer.script.impl.DefaultScriptParserorg.unitils.dbmaintainer.script.ScriptParser.implClassName.oracle=org.unitils.dbmaintainer.script.impl.OracleScriptParserorg.unitils.dbmaintainer.script.ScriptParser.implClassName.oracle9=org.unitils.dbmaintainer.script.impl.OracleScriptParserorg.unitils.dbmaintainer.script.ScriptParser.implClassName.oracle10=org.unitils.dbmaintainer.script.impl.OracleScriptParser# Set to true if characters can be escaped by using backslashes. For example '\'' instead of the standard SQL way ''''.# Note this is not standard SQL behavior and is therefore disabled by default.org.unitils.dbmaintainer.script.ScriptParser.backSlashEscapingEnabled=false # If set to true, an implementation of org.unitils.dbmaintainer.constraints.ConstraintsDisabler will be used to disable# the foreign key and not null constraints of the unit test database schema.# The ConstraintsDisabler is configured using the properties specified below. The property with key 'database.dialect'# specifies which implementation is used.dbMaintainer.disableConstraints.enabled=true# Fully qualified classname of the implementation of org.unitils.dbmaintainer.structure.ConstraintsDisablerorg.unitils.dbmaintainer.structure.ConstraintsDisabler.implClassName=org.unitils.dbmaintainer.structure.impl.DefaultConstraintsDisabler # If set to true, all sequences and identity columns are set to a sufficiently high value, so that test data can be# inserted without having manually chosen test record IDs clashing with automatically generated keys.dbMaintainer.updateSequences.enabled=true# Fully qualified classname of the implementation of org.unitils.dbmaintainer.sequences.SequenceUpdaterorg.unitils.dbmaintainer.structure.SequenceUpdater.implClassName=org.unitils.dbmaintainer.structure.impl.DefaultSequenceUpdater# Lowest acceptable value of a sequence in a unit test database. The SequenceUpdater will make sure all sequences# have this value or higher before proceedingsequenceUpdater.sequencevalue.lowestacceptable=1000 # Fully qualified classname of the implementation of org.unitils.dbmaintainer.clear.DBClearerorg.unitils.dbmaintainer.clean.DBClearer.implClassName=org.unitils.dbmaintainer.clean.impl.DefaultDBClearer# Fully qualified classname of the implementation of org.unitils.dbmaintainer.clean.DBCleaner.org.unitils.dbmaintainer.clean.DBCleaner.implClassName=org.unitils.dbmaintainer.clean.impl.DefaultDBCleaner # Indicates whether the database should be cleaned before data updates are executed by the dbMaintainer. If true, the# records of all database tables, except the ones listed in 'dbMaintainer.preserve.*' are deleteddbMaintainer.cleanDb.enabled=true # Comma separated list of database items that may not be dropped or cleared by the DB maintainer when# updating the database from scratch (dbMaintainer.fromScratch.enabled=true).# Schemas can also be preserved entirely. If identifiers are quoted (eg "" for oracle) they are considered# case sensitive. Items that do not have a schema prefix are considered to be in the default schema, which# is the first schema listed in the property database.schemaNamesdbMaintainer.preserve.schemas=dbMaintainer.preserve.tables=dbMaintainer.preserve.views=dbMaintainer.preserve.materializedViews=dbMaintainer.preserve.synonyms=dbMaintainer.preserve.sequences= # Comma separated list of tables that will not be emptied when the db maintainer performs a database# update, if the property dbMaintainer.cleanDb.enabled is set to true.# Tables listed here will still be dropped when the db maintainer performs a from scratch update. If this is not desirable# you should add the tablename to the dbMaintainer.preserve.tables property instead# Schemas can also be preserved entirely. If identifiers are quoted (eg "" for oracle) they are considered# case sensitive. Items that do not have a schema prefix are considered to be in the default schema, which# is the first schema listed in the property database.schemaNamesdbMaintainer.preserveDataOnly.schemas=dbMaintainer.preserveDataOnly.tables= # If set to true an XSD or DTD will be generated that represents the structure of the database schema. This XSD or DTD can be# used in datafiles to verify if they are up-to-date and to enable code completion.dbMaintainer.generateDataSetStructure.enabled=true# Fully qualified name of the implementation of org.unitils.dbmaintainer.structure.DataSetStructureGenerator that is used.# org.unitils.dbmaintainer.structure.impl.XsdDataSetStructureGenerator can be used to generate XSDs# org.unitils.dbmaintainer.structure.impl.DtdDataSetStructureGenerator can be used to generate DTDsorg.unitils.dbmaintainer.structure.DataSetStructureGenerator.implClassName=org.unitils.dbmaintainer.structure.impl.XsdDataSetStructureGenerator# DbUnit data set dtd file pathdataSetStructureGenerator.dtd.filename=# DbUnit data set xsd file pathdataSetStructureGenerator.xsd.dirName=# Suffix to use when generating complex types for tablesplexTypeSuffix=__type
# Fully qualified classname of the implementation of UnitilsTransactionManager that is usedorg.unitils.database.transaction.UnitilsTransactionManager.implClassName=org.unitils.database.transaction.impl.DefaultUnitilsTransactionManager# If set to true, the datasource injected onto test fields annotated with @TestDataSource or retrieved using# DatabaseUnitils#getTransactionalDataSource are wrapped in a transactional proxydataSource.wrapInTransactionalProxy=true
# Default operation that is used for getting a dbunit dataset into the database. Should be the fully qualified classname# of an implementation of org.unitils.dbunit.datasetloadstrategy.DataSetLoadStrategyDbUnitModule.DataSet.loadStrategy.default=org.unitils.dbunit.datasetloadstrategy.impl.CleanInsertLoadStrategy# Default factory that is used to create a dataset object from a file for the @DataSet annotationDbUnitModule.DataSet.factory.default=org.unitils.dbunit.datasetfactory.impl.MultiSchemaXmlDataSetFactory# Default factory that is used to create a dataset object from a file for the @ExpectedDataSet annotationDbUnitModule.ExpectedDataSet.factory.default=org.unitils.dbunit.datasetfactory.impl.MultiSchemaXmlDataSetFactory # Fully qualified classname of the data set resolverorg.unitils.dbunit.datasetfactory.DataSetResolver.implClassName=org.unitils.dbunit.datasetfactory.impl.DefaultDataSetResolver# If set to true, the data set name will be prefixed with the package name of the test (with . replaced by /)dbUnit.datasetresolver.prefixWithPackageName=true# Optional prefix for the data set file name. If it starts with '/' it is treated as an absolute path on the# file system, if not, it is treated as a classpath resource.dbUnit.datasetresolver.pathPrefix=
# Fully qualified classnames of the different, dbms specific implementations of org.dbunit.dataset.datatype.IDataTypeFactoryorg.dbunit.dataset.datatype.IDataTypeFactory.implClassName.oracle=org.dbunit.ext.oracle.OracleDataTypeFactoryorg.dbunit.dataset.datatype.IDataTypeFactory.implClassName.oracle9=org.dbunit.ext.oracle.OracleDataTypeFactoryorg.dbunit.dataset.datatype.IDataTypeFactory.implClassName.oracle10=org.dbunit.ext.oracle.OracleDataTypeFactoryorg.dbunit.dataset.datatype.IDataTypeFactory.implClassName.db2=org.dbunit.ext.db2.Db2DataTypeFactoryorg.dbunit.dataset.datatype.IDataTypeFactory.implClassName.hsqldb=org.dbunit.ext.hsqldb.HsqldbDataTypeFactoryorg.dbunit.dataset.datatype.IDataTypeFactory.implClassName.mysql=org.dbunit.ext.mysql.MySqlDataTypeFactoryorg.dbunit.dataset.datatype.IDataTypeFactory.implClassName.postgresql=org.dbunit.dataset.datatype.DefaultDataTypeFactoryorg.dbunit.dataset.datatype.IDataTypeFactory.implClassName.derby=org.dbunit.dataset.datatype.DefaultDataTypeFactoryorg.dbunit.dataset.datatype.IDataTypeFactory.implClassName.mssql=org.dbunit.ext.mssql.MsSqlDataTypeFactory
### DatabaseModule configuration #### Default behavior concerning execution of tests in a transaction. Supported values are 'disabled', 'commit' and 'rollback'.# If set to disabled, test are not executed in a transaction by default. If set to commit, each test is run in a transaction,# which is committed. If set to rollback, each test is run in a transaction, which is rolled back.DatabaseModule.Transactional.value.default=commit ### MockModule configuration ###mockModule.logFullScenarioReport=falsemockModule.logObservedScenario=falsemockModule.logDetailedObservedScenario=falsemockModule.logSuggestedAsserts=false ### EasyMockModule configuration #### Default value for order checking of method invocation on mocks. Supported values are 'none' and 'strict'EasyMockModule.RegularMock.invocationOrder.default=none# Default value for the calls property of mocks. Supported values are 'lenient' and 'strict'EasyMockModule.RegularMock.calls.default=strict# Default value for order checking of method invocation on mocks. Supported values are 'none' and 'strict'EasyMockModule.Mock.invocationOrder.default=noneEasyMockModule.Mock.calls.default=strictEasyMockModule.Mock.order.default=lenientEasyMockModule.Mock.dates.default=strictEasyMockModule.Mock.defaults.default=ignore_defaults# Indicates whether after every test, the expected method calls are verified on all mock objects that were injected on# fields annotated with @Mock or created with EasyMockUnitils.createMock (i.e. the verify() method is invoked on all# these mocks.EasyMockModule.autoVerifyAfterTest.enabled=true ### InjectModule configuration #### Mode of accessing propertiesInjectModule.InjectIntoStatic.restore.default=old_valueInjectModule.InjectIntoByType.propertyAccess.default=fieldInjectModule.InjectIntoStaticByType.restore.default=old_valueInjectModule.InjectIntoStaticByType.propertyAccess.default=fieldInjectModule.TestedObject.createIfNull.enabled=true ### HibernateModule configuration ###HibernateModule.configuration.implClassName=org.hibernate.cfg.AnnotationConfiguration ### JpaModule configuration #### Indicates the JPA persistence provider that is used. Supported values are 'hibernate', 'toplink' and 'openjpa'jpa.persistenceProvider=hibernate org.unitils.orm.jpa.util.JpaProviderSupport.implClassName.hibernate=org.unitils.orm.jpa.util.provider.hibernate.HibernateJpaProviderSupportorg.unitils.orm.jpa.util.JpaProviderSupport.implClassName.toplink=org.unitils.orm.jpa.util.provider.toplink.ToplinkJpaProviderSupportorg.unitils.orm.jpa.util.JpaProviderSupport.implClassName.openjpa=org.unitils.orm.jpa.util.provider.openjpa.OpenJpaProviderSupport ### SpringModule configuration ###SpringModule.applicationContextFactory.implClassName=org.unitils.spring.util.ClassPathXmlApplicationContextFactory spring.core.someClass.name=org.springframework.core.io.Resource
### IOModule configuration& #### The list of conversion strategies used.# The propertiesConversionStrategy will convert a *.properties file to a properties object# The StringConversationStrategy will to the same from a .txt file to a String# It is possible to add you own strategies, or override these existing ones.IOModule.conversion.default=org.unitils.io.conversion.impl.PropertiesConversionStrategy,org.unitils.io.conversion.impl.StringConversionStrategyIOModule.conversion.custom= IOModule.encoding.default=ISO-8859-1# If set to true, the file name will be prefixed with the package name of the test (with . replaced by /)IOModule.file.prefixWithPackageName=true# Optional prefix for the file name. If it starts with '/' it is treated as an absolute path on the# file system, if not, it is treated as a classpath resource.IOModule.file.pathPrefix= # If set to true, all temp files and directories created during a test will be deleted after the test.IOModule.temp.cleanupAfterTest=false# The root directory for all temp files and directories. If not specified, the default user temp dir will be used.IOModule.temp.rootTempDir=
org.unitils.io.reader.FileResolvingStrategyFactory.implClassName=org.unitils.io.reader.impl.DefaultFileResolvingStrategyFactoryorg.unitils.io.reader.ReadingStrategyFactory.implClassName=org.unitils.io.reader.impl.FileReadingStrategyFactoryorg.unitils.io.filecontent.FileContentReaderFactory.implClassName=org.unitils.io.filecontent.impl.DefaultFileContentReaderFactoryorg.unitils.io.temp.TempServiceFactory.implClassName=org.unitils.io.temp.impl.DefaultTempServiceFactory
浏览: 930372 次
来自: 厦门
浏览量:311212
书已买,赞一个
qja 写道我靠。。我的没有show dependency 。 ...
cizezsy 写道请问下有没有勘误表啊?书上的代码有一些错漏 ...
请问下有没有勘误表啊?书上的代码有一些错漏的地方}

我要回帖

更多关于 微信强制升级才能登陆 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信