Java 运行Android Tests setUp()方法会被多次调用

Java 运行Android Tests setUp()方法会被多次调用,java,android,eclipse,junit4,Java,Android,Eclipse,Junit4,我正在为我的android应用程序创建一个测试套件,并使用此设置方法 private static final String TAG_NAME = "TESTING_SUITE"; public TestingMusicDAO musicDAO; public List<Song> songs; public Instrumentation instr; MusicService musicService;

我正在为我的android应用程序创建一个测试套件,并使用此设置方法

    private static final String TAG_NAME = "TESTING_SUITE";
        public TestingMusicDAO musicDAO;
        public List<Song> songs;
        public Instrumentation instr;
        MusicService musicService;
    @Override
    public void setUp() throws Exception {
        instr = this.getInstrumentation();
        Log.d(TAG_NAME, "Setting up testing songs");
        musicDAO = new TestingMusicDAO(instr.getContext());
        musicService = new MusicServiceImpl(musicDAO);
        musicDAO.getAllSongsFromFile();
        songs = musicDAO.getAllSongs();
        for(Song song : songs)
            Log.d( TAG_NAME, song.toString() );
     }
private static final String TAG_NAME=“TESTING_SUITE”;
公开测试音乐道音乐道;
公开列表歌曲;
公共仪器仪表研究所;
音乐服务;音乐服务;
@凌驾
public void setUp()引发异常{
instr=this.getInstrumentation();
Log.d(标签名称,“设置测试歌曲”);
musicDAO=新测试musicDAO(instr.getContext());
musicService=新的musicService MPL(musicDAO);
musicDAO.getAllSongsFromFile();
歌曲=音乐dao.getAllSongs();
用于(歌曲:歌曲)
Log.d(TAG_NAME,song.toString());
}
然后使用python工具从文本文件创建这些测试

public void test1() {
    List<Song> testPlaylist;
    String testArtist = ("The Beatles");
    String actualArtist = ("TheBeatles"); 
    testPlaylist = testingPlaySongsByKeyword(testArtist);
    if(testPlaylist.isEmpty()){
        fail("No Songs Were Found");
    } else {
        for( Song loopsongs : testPlaylist){
            if (!(loopsongs.getArtist().equals(actualArtist))){
                fail("Song Doesnt Contain the artist" + actualArtist + "... Contains ->" + loopsongs.getArtist());
            }
        }
   }
}
public void test1(){
列出测试播放列表;
弦乐测试家=(“披头士”);
弦乐演奏家=(“披头士”);
testPlaylist=TestingPlaysSongsByKeyword(测试者);
if(testPlaylist.isEmpty()){
失败(“未找到歌曲”);
}否则{
用于(歌曲循环歌曲:testPlaylist){
如果(!(loopsongs.getArtister().equals(actualArtist))){
失败(“歌曲不包含艺术家”+actualArtist+“…包含->”+loopsongs.getArtist());
}
}
}
}

每当其中一个被称为“音乐之岛”时,它就会再生。如何阻止调用安装方法?如果您不调用,请执行此操作。JUnit的设计是
setUp()
tearDown()
每个测试执行一次。如果您希望每个类都完成,请在构造函数中完成。只需确保在类中没有更改任何内容。每次测试执行一次的原因是为了确保所有测试都以相同的数据开始。

我遇到了相同的基本问题。我希望能够测试数据库的结构,所以我在setUp方法中创建它,并在tearDown中删除它。使用构造函数无法解决在执行所有测试后删除数据库的问题,因此我使用了一些可重入逻辑:

static int testsExecutedSoFar = 0;
static boolean isFirstRun = true;

@Override
protected void setUp() throws Exception {
    if(isFirstRun){
        createDb();
        isFirstRun = false;
    }       
}

@Override
protected void tearDown() throws Exception{
    testsExecutedSoFar++;
    if (testsExecutedSoFar == totalNumberOfTestCases())
        deleteDb();     
}

private int totalNumberOfTestCases() {
    return countTestCases()+1; //have to add one for testandroidtestcasesetupproperly added by AndroidTestCase
}
这些字段必须是静态的,因为JUnit会为每次运行创建一个新的类实例。由于AndroidTestCase将自己的测试(TestAndRoidTestCaseSetupRightly)添加到测试套件中,但它不计入countTestCases()返回的数字,因此必须添加magic 1

虽然有点丑陋,但它确实起到了作用。

您可以使用JUnit中的注释和注释

@BeforeClass
public static void test_setUp_Once(){
  // Code which you want to be executed only once
  createDb();
}

@AfterClass
public static void test_tearDown_Once(){
  // Code which you want to be executed only once
  deleteDb();
}

注意:您需要声明这些方法
static
才能正常工作。

因此我将创建测试类的构造函数?这是我所知道的唯一只运行一次的函数。你最好按照jUnit所期望的方式编写测试,但最终会比较轻松。好吧,只是痛苦地为每个测试生成一个数据库。除了使用构造函数,你可以使用Vikash已经提到的
@BeforeClass
@AfterClass
。@Vikash kumar verna的答案是正确的。在JUnit4中,对每个测试用例执行一次Ctor,因为我假设它为每个测试用例创建一个新对象。