玩转单元測试之DBUnit

本文同一时候发表在:http://www.cnblogs.com/wade-xu/p/4547381.html

DBunit 是一种扩展于JUnit的数据库驱动測试框架,它使数据库在測试过程之间处于一种已知状态。假设一个測试用例对数据库造成了破坏性影响,它能够帮助避免造成后面的測试失败或者给出错误结果。

尽管不是什么新奇货,但近期正好用到。就把学到的跟大家分享一下。

关键词:数据库层測试,DAO层測试,DBUnit教程,DBUnit入门。DBUnit实例,Sring中结合DBUnit对Dao层測试

文件夹
   简单介绍
   前提条件
   Maven配置
   准备工作
   实例具体解释
       測试基类
       关于数据集
       Example 1 FlatXmlDataSet
       Example 2 ReplacementDataSet
       Example 3 XlsDataSet
       Example 4 QueryDataSet
       Example 5 other
   Troubleshooting
   參考

简单介绍

DBunit通过维护真实数据库与数据集(IDataSet)之间的关系来发现与暴露測试过程中的问题。IDataSet 代表一个或多个表的数据。

此处IDataSet能够自建。能够由数据库导出,并以多种方式体现,xml文件、XLS文件和数据库查询数据等。

基于DBUnit 的測试的主要接口是IDataSet,能够将数据库模式的所有内容表示为单个IDataSet 实例。这些表本身由Itable 实例来表示。

IDataSet 的实现有非常多,每个都相应一个不同的数据源或载入机制。最经常使用的几种 IDataSet 实现为:

FlatXmlDataSet :数据的简单平面文件 XML 表示

QueryDataSet :用 SQL 查询获得的数据

DatabaseDataSet :数据库表本身内容的一种表示

XlsDataSet :数据的excel 表示

前提条件

  • JDK 1.7
  • Maven 3

Maven配置

pom里加入下面的dependencies

    <dependency>
        <groupId>org.dbunit</groupId>
        <artifactId>dbunit</artifactId>
        <version>2.5.1</version>
    </dependency>

实例具体解释

測试流程大概是这种。建立数据库连接-> 备份表 -> 调用Dao层接口 -> 从数据库取实际结果-> 事先准备的期望结果 -> 断言 -> 回滚数据库 -> 关闭数据库连接

由于每一个測试都有非常多共性,所以提取成抽象基类例如以下。

測试基类:

package com.demo.test.dao.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;

import javax.sql.DataSource;

import org.dbunit.database.DatabaseConfig;
import org.dbunit.database.DatabaseConnection;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.database.QueryDataSet;
import org.dbunit.dataset.DataSetException;
import org.dbunit.dataset.DefaultDataSet;
import org.dbunit.dataset.DefaultTable;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.ReplacementDataSet;
import org.dbunit.dataset.excel.XlsDataSet;
import org.dbunit.dataset.xml.FlatXmlDataSet;
import org.dbunit.dataset.xml.FlatXmlDataSetBuilder;
import org.dbunit.ext.mysql.MySqlDataTypeFactory;
import org.dbunit.operation.DatabaseOperation;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;

/**
 * @Description: BaseDaoTest class
 * @author wadexu
 *
 * @updateUser
 * @updateDate
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "file:src/test/resources/mvc-dispatcher-servlet.xml")
@TransactionConfiguration(defaultRollback = true)
public abstract class BaseDaoTest extends AbstractTransactionalJUnit4SpringContextTests {

    @Autowired
    private DataSource dataSource;

    private static IDatabaseConnection conn;

    private File tempFile;

    public static final String ROOT_URL = System.getProperty("user.dir") + "/src/test/resources/";

    @Before
    public void setup() throws Exception {
        //get DataBaseSourceConnection
        conn = new DatabaseConnection(DataSourceUtils.getConnection(dataSource));

        //config database as MySql
        DatabaseConfig dbConfig = conn.getConfig();
        dbConfig.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY,  new MySqlDataTypeFactory());

    }

    @After
    public void teardown() throws Exception {
        if (conn != null) {
            conn.close();
        }

    }

    /**
     *
     * @Title: getXmlDataSet
     * @param name
     * @return
     * @throws DataSetException
     * @throws IOException
     */
    protected IDataSet getXmlDataSet(String name) throws DataSetException, IOException {
        FlatXmlDataSetBuilder builder = new FlatXmlDataSetBuilder();
        builder.setColumnSensing(true);
        return builder.build(new FileInputStream(new File(ROOT_URL + name)));
    }

    /**
     * Get DB DataSet
     *
     * @Title: getDBDataSet
     * @return
     * @throws SQLException
     */
    protected IDataSet getDBDataSet() throws SQLException {
        return conn.createDataSet();
    }

    /**
     * Get Query DataSet
     *
     * @Title: getQueryDataSet
     * @return
     * @throws SQLException
     */
    protected QueryDataSet getQueryDataSet() throws SQLException {
        return new QueryDataSet(conn);
    }

    /**
     * Get Excel DataSet
     *
     * @Title: getXlsDataSet
     * @param name
     * @return
     * @throws SQLException
     * @throws DataSetException
     * @throws IOException
     */
    protected XlsDataSet getXlsDataSet(String name) throws SQLException, DataSetException,
            IOException {
        InputStream is = new FileInputStream(new File(ROOT_URL + name));

        return new XlsDataSet(is);
    }

    /**
     * backup the whole DB
     *
     * @Title: backupAll
     * @throws Exception
     */
    protected void backupAll() throws Exception {
        // create DataSet from database.
        IDataSet ds = conn.createDataSet();

        // create temp file
        tempFile = File.createTempFile("temp", "xml");

        // write the content of database to temp file
        FlatXmlDataSet.write(ds, new FileWriter(tempFile), "UTF-8");
    }

    /**
     * back specified DB table
     *
     * @Title: backupCustom
     * @param tableName
     * @throws Exception
     */
    protected void backupCustom(String... tableName) throws Exception {
        // back up specific files
        QueryDataSet qds = new QueryDataSet(conn);
        for (String str : tableName) {

            qds.addTable(str);
        }
        tempFile = File.createTempFile("temp", "xml");
        FlatXmlDataSet.write(qds, new FileWriter(tempFile), "UTF-8");

    }

    /**
     * rollback database
     *
     * @Title: rollback
     * @throws Exception
     */
    protected void rollback() throws Exception {

        // get the temp file
        FlatXmlDataSetBuilder builder = new FlatXmlDataSetBuilder();
        builder.setColumnSensing(true);
        IDataSet ds =builder.build(new FileInputStream(tempFile));

        // recover database
        DatabaseOperation.CLEAN_INSERT.execute(conn, ds);
    }

    /**
     * Clear data of table
     *
     * @param tableName
     * @throws Exception
     */
    protected void clearTable(String tableName) throws Exception {
        DefaultDataSet dataset = new DefaultDataSet();
        dataset.addTable(new DefaultTable(tableName));
        DatabaseOperation.DELETE_ALL.execute(conn, dataset);
    }

    /**
     * verify Table is Empty
     *
     * @param tableName
     * @throws DataSetException
     * @throws SQLException
     */
    protected void verifyTableEmpty(String tableName) throws DataSetException, SQLException {
        Assert.assertEquals(0, conn.createDataSet().getTable(tableName).getRowCount());
    }

    /**
     * verify Table is not Empty
     *
     * @Title: verifyTableNotEmpty
     * @param tableName
     * @throws DataSetException
     * @throws SQLException
     */
    protected void verifyTableNotEmpty(String tableName) throws DataSetException, SQLException {
        Assert.assertNotEquals(0, conn.createDataSet().getTable(tableName).getRowCount());
    }

    /**
     *
     * @Title: createReplacementDataSet
     * @param dataSet
     * @return
     */
    protected ReplacementDataSet createReplacementDataSet(IDataSet dataSet) {
        ReplacementDataSet replacementDataSet = new ReplacementDataSet(dataSet);

        // Configure the replacement dataset to replace ‘[NULL]‘ strings with null.
        replacementDataSet.addReplacementObject("[null]", null);

        return replacementDataSet;
    }
}

##转载注明出处: http://www.cnblogs.com/wade-xu/p/4547381.html

我这里介绍的測试案例都是基于Spring项目的,假设是普通的项目,怎样配置数据库连接例如以下:

public static void init() throws Exception {

        // get DataBaseSourceConnection
        testDataSource = new BasicDataSource();
        testDataSource.setDriverClassName("com.mysql.jdbc.Driver");
        testDataSource.setUrl("jdbc:mysql://10.52.26.11:3306/Test?

useUnicode=true&characterEncoding=utf8&allowMultiQueries=true");
        testDataSource.setUsername("xxx");
        testDataSource.setPassword("xxxxx");
        connection = new DatabaseDataSourceConnection(testDataSource);
        ImporterManager.setJdbcTemplate(new JdbcTemplate(testDataSource));
    }

关于数据集

DBUnit能够把全部表的记录存在一个数据集中:既能够是数据库中的表,也能够是文件里的数据。我们在此用FlatXmlDataSet来讲述。

在FlatXmlDataSet相应的XML文件中,元素名称相应数据库表名,元素的属性(attribute)相应表的列。如:

<dataset>
    <Person Name="Kirin" Age="31" Location="Beijing"/>
    <Person Name="Jade" Age="30"/>
</dataset>

要注意,假设数据库中某一条字段为null。在flat XML中将不会显示该attribute。

另外,FlatXmlDataSet用XML文件里该表的第一行数据来制定表的结构。因此,假设数据库中某个字段全部记录都为null,或者恰巧第一条记录为null,那么得到的表结构与原数据库的表结构就不一致了,測试就会失败。FlatXmlDataSet中存在一个column sensing的概念,在从文件载入数据时,将该属性设置为true。就会依据第一行展现出来的表结构。自己主动将别的行的列补齐。

顺便提一句,DBUnit中还存在还有一种格式的数据集XmlDataSet,在XmlDataSet相应的XML文件中,用元素的子元素相应表的列。如:

<dataset>
    <Person>
        <Name>Kirin</Name>
        <Age>31</Age>
        <Location>Beijing</Location>
    </Person>
    <Person>
        <Name>Jade</Name>
        <Age>30</Age>
        <Location/>
    </Person>
</dataset>

null的表示方法如红色部分。

##转载注明出处: http://www.cnblogs.com/wade-xu/p/4547381.html

Example 1

关于FlatXmlDataSet

package com.demo.test.dao.impl;

import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.dbunit.Assertion;
import org.dbunit.database.QueryDataSet;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.ITable;
import org.dbunit.dataset.ReplacementDataSet;
import org.dbunit.dataset.excel.XlsDataSet;
import org.dbunit.dataset.filter.DefaultColumnFilter;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

import com.demo.test.dao.BundleDao;
import com.demo.test.dao.VersionDao;
import com.demo.test.entity.InfoEntity;
import com.demo.test.exception.DBException;/**
 * @Description: BundleDaoImpl Test via DBUnit
 * @author wadexu
 *
 * @updateUser
 * @updateDate
 */
public class BundleDaoImplDBUnitTest_Demo extends BaseDaoTest {

    @Autowired
    private BundleDao bundleDao;

    @Autowired
    private VersionDao versionDao;private static final String TABLE_DOCUMENTS_MASTER = "Documents_Master";
    private static final String TABLE_FILE_VERSION = "FILE_VERSION";
    private static final String VERSION_VALUE = "11.0.3";

    @Test
    public void testInsertBundles_1() throws Exception {
        backupCustom(TABLE_FILE_VERSION, TABLE_DOCUMENTS_MASTER);

        bundleDao.deleteAll();

        bundleDao.insertBundle(getBundles());

        //get actual tableInfo from DB
        IDataSet dbDataSet = getDBDataSet();
        ITable dbTable = dbDataSet.getTable(TABLE_DOCUMENTS_MASTER);

        //get expect Information from xml file
        IDataSet xmlDataSet = getXmlDataSet("expect_documents_master.xml");
        ITable xmlTable = xmlDataSet.getTable(TABLE_DOCUMENTS_MASTER);

        //exclude some columns which don‘t want to compare result
        dbTable = DefaultColumnFilter.excludedColumnsTable(dbTable, new String[]{"IndexId", "DM_VERSION_ID"});
        xmlTable = DefaultColumnFilter.excludedColumnsTable(xmlTable, new String[]{"IndexId", "DM_VERSION_ID"});

        Assertion.assertEquals(xmlTable, dbTable);

        rollback();
    }
}

首先我备份了两张用到的表,当然也能够备份全部的表,基类都有写这些方法 (backupCustom, backupAll)

然后调用Dao层提供的方法。删除全部数据,接着插入Bundle数据, getBundles()是我的私有方法,构造insertBundle方法所需的数据

接下来,从DB里取实际数据, 用ITable的形式来表示表的实际内容

期望结果是从已准备好的xml文件读取, getxmlDataSet方法里用到了我上文所述的column sensing的概念, setColumnSensing=true, 前提是xml文件的第一行数据的列字段要全。和数据里的表结构一致。

<?

xml version=‘1.0‘ encoding=‘UTF-8‘?

>
<dataset>
  <Documents_Master IndexId="77" No="1" Retired="Y" GeneralCategory="Financial" DM_VERSION_ID="13" SOURCE="DBUnit"/>
  <Documents_Master IndexId="78" No="0" Retired="N" GeneralCategory="test" DM_VERSION_ID="13"/>
</dataset>

在断言两张表之前,由于有些字段我不想比較,比方ID字段,它的值是动态的,无法事先定义好期望结果,所以能够用DefaultColumnFilter里的excludedColumnsTable方法来将指定字段给排除在比較范围之外。

相同还有includedColumnsTable方法能够指定想要比較的字段。

最后回滚数据库。

Example 2

假设插入数据库的数据非常多字段的值都是null, FlatXmlDataSet相应的XML文件中的数据该怎么定义第一行呢?

这时候ReplacementDataSet就能够登场了。

   @Test
    public void testInsertBundles_2() throws Exception {
        backupCustom(TABLE_FILE_VERSION, TABLE_DOCUMENTS_MASTER);

        bundleDao.deleteAll();

        bundleDao.insertBundle(getBundles());

        //get actual tableInfo from DB
        IDataSet dbDataSet = getDBDataSet();
        ITable dbTable = dbDataSet.getTable(TABLE_DOCUMENTS_MASTER);

        //get expect Information from xml file
        IDataSet xmlDataSet = getXmlDataSet("expect_documents_master_2.xml");
        // handle null value, replace "[null]" strings with null
        ReplacementDataSet replacementDataSet = createReplacementDataSet(xmlDataSet);
        ITable xmlTable = replacementDataSet.getTable(TABLE_DOCUMENTS_MASTER);

        //exclude some columns which don‘t want to compare result
        dbTable = DefaultColumnFilter.excludedColumnsTable(dbTable, new String[]{"IndexId", "DM_VERSION_ID"});
        xmlTable = DefaultColumnFilter.excludedColumnsTable(xmlTable, new String[]{"IndexId", "DM_VERSION_ID"});

        Assertion.assertEquals(xmlTable, dbTable);

        rollback();
    }

我的expect_documents_master_2.xml 文件例如以下:

<?xml version=‘1.0‘ encoding=‘UTF-8‘?

>
<dataset>
  <Documents_Master IndexId="77" No="1" Retired="Y" GeneralCategory="[null]" DM_VERSION_ID="13" SOURCE="[null]"/>
  <Documents_Master IndexId="78" No="0" Retired="N" DM_VERSION_ID="13"/>
</dataset>

空元素的字段须要一个"[null]"占位符,然后用 replacementDataSet.addReplacementObject("[null]", null) 替换成null, 详见基类BaseDaoTest里的方法createReplacementDataSet.

Example 3

关于XlsDataSet

 @Test
    public void testInsertBundles_Excel() throws Exception {
        backupCustom(TABLE_FILE_VERSION, TABLE_DOCUMENTS_MASTER);

        bundleDao.deleteAll();
        bundleDao.insertBundle(getBundles());
//get actual tableInfo from DB
        IDataSet dbDataSet = getDBDataSet();
        ITable dbTable = dbDataSet.getTable(TABLE_DOCUMENTS_MASTER);

        //get expect result from xls file
        XlsDataSet xlsDataSet = getXlsDataSet("expect_documents_master.xls");
        // table name is sheet name
        ITable xlsTable = xlsDataSet.getTable("Sheet1");

        //column filter, only compare the column in xls
        dbTable = DefaultColumnFilter.includedColumnsTable(dbTable, xlsTable.getTableMetaData().getColumns());  

        Assertion.assertEquals(xlsTable, dbTable);

        rollback();
    }

这个样例的期望结果是定义在excel里的,眼下仅仅支持xls文件,即Excel97-2003

这里用到了includedColumnsTable,仅仅比較excel里定义的那些字段。

##转载注明出处: http://www.cnblogs.com/wade-xu/p/4547381.html

Example 4

QueryDataSet

    @Test
    public void testQueryBundles() throws Exception {
        backupCustom(TABLE_FILE_VERSION, TABLE_DOCUMENTS_MASTER);

        bundleDao.insertBundle(getBundles());

        List<InfoEntity> list = bundleDao.queryBundles();

        //get expect result from DB
        QueryDataSet queryDataSet = getQueryDataSet();
        queryDataSet.addTable("test", "select * from Documents_Master");
        ITable dbTable = queryDataSet.getTable("test");

        Assert.assertEquals(dbTable.getRowCount(), list.size());

        rollback();
    }

通过自己的query语句查到的结果作为期望结果与调用Dao层取得的实际结果比較断言。

Example 5

    @Test
    public void testDeleteAll() throws Exception {
        backupCustom(TABLE_FILE_VERSION, TABLE_DOCUMENTS_MASTER);

        bundleDao.insertBundle(getBundles());
        verifyTableNotEmpty(TABLE_DOCUMENTS_MASTER);

        bundleDao.deleteAll();
        verifyTableEmpty(TABLE_DOCUMENTS_MASTER);

        rollback();
    }
    

Run as JUnit

測试结果例如以下图,毕竟是实际读写数据库,速度还是比較慢的。 49秒多。(慢跟我的本地环境连远程数据库也有非常大关系)

##转载注明出处: http://www.cnblogs.com/wade-xu/p/4547381.html

Troubleshooting

1. java.lang.NoSuchMethodError: org.apache.poi.hssf.usermodel.HSSFDateUtil.isCellDateFormatted(Lorg/apache/poi/hssf/usermodel/HSSFCell;

--用最新的包2.5.1能够解决问题

2. 控制台报警

WARN org.dbunit.dataset.AbstractTableMetaData - Potential problem found: The configured data type factory ‘class org.dbunit.dataset.datatype.DefaultDataTypeFactory‘ might cause problems with the current database ‘MySQL‘ (e.g. some datatypes may not be supported
properly).

In rare cases you might see this message because the list of supported database products is incomplete (list=[derby]). If so please request a java-class update via the forums.If you are using your own IDataTypeFactory extending DefaultDataTypeFactory, ensure
that you override getValidDbProducts() to specify the supported database products.

--须要配置例如以下属性:

DatabaseConfig dbConfig = conn.getConfig();

dbConfig.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new MySqlDataTypeFactory());

3. 如遇到这个错误

Extra columns on line x. Those columns will be ignored. Please add the extra columns to line 1, or use a DTD to make sure the value of those columns are populated.

则须要用setColumnSensing

FlatXmlDataSetBuilder builder = new FlatXmlDataSetBuilder();

builder.setColumnSensing(true);

IDataSet dataSet = builder.build(new File("test.xml"));

4. 有关联的表 须要一起backup

5. 基类BaseDaoTest 由于没有@Test測试方法,所以须要写成抽象类,不然会出现 java.lang.Exception: No runnable methods

6. 假设想让DBUnit支持Excel2007 xlsx格式的文件的话,须要自己下载源代码。把org.apache.poi.hssf 改成 xssf, 或者ss支持新老格式,又一次编译, 再依赖进来。

參考

官方文档: http://dbunit.sourceforge.net/

感谢阅读,假设您认为本文的内容对您的学习有所帮助,您能够点击右下方的推荐button。您的鼓舞是我创作的动力。

##转载注明出处: http://www.cnblogs.com/wade-xu/p/4547381.html

时间: 2024-12-13 14:52:18

玩转单元測试之DBUnit的相关文章

玩转单元測试之WireMock -- Web服务模拟器

WireMock 是一个灵活的库用于 Web 服务測试,和其它測试工具不同的是.WireMock 创建一个实际的 HTTPserver来执行你的 Web 服务以方便測试. 它支持 HTTP 响应存根.请求验证.代理/拦截.记录和回放. 而且能够在单元測试下使用或者部署到測试环境. 它能够用在哪些场景下: 測试移动应用依赖于第三方REST APIs 创建高速原型的APIs 注入否则难于模拟第三方服务中的错误 不论什么单元測试的代码依赖于web服务的 文件夹 前提条件 Maven配置 准备工作 Ex

[iOS翻译]《iOS7 by Tutorials》在Xcode 5里使用单元測试(上)

简单介绍: 单元測试是软件开发的一个重要方面.毕竟,单元測试能够帮你找到bug和崩溃原因,而程序崩溃是Apple在审查时拒绝app上架的首要原因. 单元測试不是万能的,但Apple把它作为开发工具包的一部分,不仅让你创作的APP更稳定,并且提供了一致.有趣的用户体验,这些都是让用户给你五星评价的源泉.iOS7提供了一个升级的单元測试框架.让你在Xcode中执行单元測试更为easy.当你完毕这一章节,你将学会怎样给现有app加入測试--并有可能培养出对编写測试的热爱! /* 本文翻译自<iOS7

C语言单元測试

对于敏捷开发来说,单元測试不可缺少,对于Java开发来说,JUnit非常好,对于C++开发,也有CPPUnit可供使用,而对于传统的C语言开发,就没有非常好的工具可供使用,能够找到的有这么几个工具: CuTest -- CuTest(Cute Test)是一个很easy的C语言单元測试工具.在使用它的时候,仅仅须要包括两个文件“CuTest.c CuTest.h”,然后就能够写測试用例,进行測试了.它对用例差点儿没有管理功能,报表输出也很easy,能够用来试验单元測试的基本想法. CUnit -

Android 进行单元測试难在哪-part3

原文链接 : HOW TO MAKE OUR ANDROID APPS UNIT TESTABLE (PT. 1) 原文作者 : Matthew Dupree 译文出自 : 开发技术前线 www.devtf.cn 译者 : chaossss 校对者: tiiime 状态 : 完毕 在 Android 应用中进行单元測试非常困难.有时候甚至是不可能的.在之前的两篇博文中,我已经向大家解释了在 Android 中进行单元測试如此困难的原因.而上一篇博文我们通过分析得到的结论是:正是 Google 官

利用Continuous Testing实现Eclipse环境自己主动单元測试

当你Eclipse环境中改动项目中的某个方法时,你可能因为各种原因没有执行单元測试,结果代码提交,悲剧就可能随之而来. 所幸infinitest(http://infinitest.github.io/)提供了一个Continuous Testing插件,以及时自己主动执行单元測试.尽管会多占一些CPU资源,但开发者的硬件谁会不留一点余地呢?大不了,音乐.视频.360卸载就OK了.安装方法有两种: (1)使用"Install new software",输入地址:http://infi

在Eclipse中使用JUnit4进行单元測试(0基础篇)

本文绝大部分内容引自这篇文章: http://www.devx.com/Java/Article/31983/0/page/1 我们在编写大型程序的时候,须要写成千上万个方法或函数,这些函数的功能可能非常强大,但我们在程序中仅仅用到该函数的一小部分功能,而且经过调试能够确定,这一小部分功能是正确的.可是,我们同一时候应该确保每个函数都全然正确,由于假设我们今后假设对程序进行扩展,用到了某个函数的其它功能,而这个功能有bug的话,那绝对是一件非常郁闷的事情.所以说,每编写完一个函数之后,都应该对这

新手学測试----Unit Test(单元測试)

在程序猿做项目的过程中,每当完毕一个功能,首先自己须要对完毕的功能进行測试.我如今正在做的项目用的工具是VS2012.那么接下来,就说一说在VS2012中是怎样创建单元測试的. 怎样创建单元測试? 在VS2012中,右键类名默认是没有创建单元測试的选项的,得须要设置加入.工具-->自己定义: 然后选择命令-->上下文菜单-->编辑器上下文菜单|代码窗体.然后找到创建单元測试,并将其上下移动到下图所看到的位置: 然后又一次打开VS.在类名上右键就能够看到灰色的创建单元測试,处于禁用状态:

单元測试的优点

对于单元測试.我慢慢的用得多起来.前不久.还对这个东西朦朦胧胧,认为非常神奇. 如今,我认为单元測试真是极好的. 好在哪里呢?就是好来就是好! 靠,这又不是某D某主义,得讲理.怎么个好法,要说出理由. 好吧.我认为单元測试能够 1.保证代码质量 2.提高开发效率 比方说,这2天我与还有一位同事共同开发某模块.他搞前端,我写server端.他要调用我的方法. 开发是并行的,我在写方法的时候,他的界面还没好,那怎么确保我的方法正确呢?不可能等他写好界面,写好调用我方法的代码,然后我俩再一起測试吧?

【Android进阶】Junit单元測试环境搭建以及简单有用

单元測试的目的 首先.Junit单元測试要实现的功能,就是用来測试写好的方法是否可以正确的运行,一般多用于对业务方法的測试. 单元測试的环境配置 1.在AndroidManifest清单文件的Application节点下.引入单元測试使用的库 2.在AndroidManifest清单文件与Application节点平行的节点中.加入instrumentation节点 以下是一个完整的配置的代码 <manifest xmlns:android="http://schemas.android.