Is there a recommended way for Solr 3.6 JUnit test

2019-05-26 16:13发布

问题:

I wonder if there is any best practice for junit testing of Solr 3.6. I want to automate testing of the Solr schema. Earlier posts mentioned the EmbeddedSolrServer. This class seems to have been abandoned from any version between 1.4 an 3.6. I use Spring 3.0.x and Maven for the project. The options I considered are:

  1. writing a Junit Test Runner
  2. put the jetty startup code in the @Before or @BeforeClass method
  3. start a solr server in maven (probably not a good option)
  4. put some code in the spring test-context

回答1:

I've used something similar to what's on this page to run these kinds of tests, all done with EmbeddedSolrServer on Solr 3.4.0. This is a simple approach, but if you want to automate Solr schema testing, it could be enough and isn't hard to implement.
It basically boils down to:
Adding references to junit, solr-core, slf4j-simpleand servlet-apito your pom.xml:

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.7</version>
        <type>jar</type>
        <scope>test</scope>
    </dependency>
    <!-- dependencies needed for Solr integration test-->
    <dependency>
        <groupId>org.apache.solr</groupId>
        <artifactId>solr-core</artifactId>
        <version>1.4.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-simple</artifactId>
        <version>1.6.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
        <scope>test</scope>
    </dependency>

And as an example test case, he adds this:

import java.io.IOException;
import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
import org.apache.solr.util.AbstractSolrTestCase;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.params.SolrParams;
import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.assertEquals;

public class SolrSearchConfigTest extends AbstractSolrTestCase {

    private SolrServer server;

    @Override
    public String getSchemaFile() {
        return "solr/conf/schema.xml";
    }

    @Override
    public String getSolrConfigFile() {
        return "solr/conf/solrconfig.xml";
    }

    @Before
    @Override
    public void setUp() throws Exception {
        super.setUp();
        server = new EmbeddedSolrServer(h.getCoreContainer(), h.getCore().getName());
    }

    @Test
    public void testThatNoResultsAreReturned() throws SolrServerException {
        SolrParams params = new SolrQuery("text that is not found");
        QueryResponse response = server.query(params);
        assertEquals(0L, response.getResults().getNumFound());
    }

    @Test
    public void testThatDocumentIsFound() throws SolrServerException, IOException {
        SolrInputDocument document = new SolrInputDocument();
        document.addField("id", "1");
        document.addField("name", "my name");

        server.add(document);
        server.commit();

        SolrParams params = new SolrQuery("name");
        QueryResponse response = server.query(params);
        assertEquals(1L, response.getResults().getNumFound());
        assertEquals("1", response.getResults().get(0).get("id"));
    }
}

edit: I haven't used Solr in quite a while, but I think this could still be a good starting point.



回答2:

This is my take on it. It doesn't extend AbstractSolrTestCase, just a regular test class.

import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;

import java.io.File;
import java.io.IOException;

import org.apache.commons.io.FileUtils;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.client.solrj.response.UpdateResponse;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.core.CoreContainer;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class EmbeddedSolrServerTest {

    private static final int SUCCESS = 0;
    private final String indexLocation = "tomcat7/apps/apache-solr-3.6.0";
    private EmbeddedSolrServer server;

    @Before
    public void setUp() throws Exception {
        System.setProperty("solr.solr.home", indexLocation);
        CoreContainer coreContainer = new CoreContainer.Initializer().initialize();
        server = new EmbeddedSolrServer(coreContainer, "collection1");
    }

    @After
    public void tearDown() throws Exception {
        server.shutdown();
        removeIndexDirectory();
    }

    @Test
    public void testSolrSchema01() throws Exception {
        SolrInputDocument doc1 = new SolrInputDocument();
        doc1.addField("id", "123");
        doc1.addField("something_txt", "super wombat");
        UpdateResponse ur = server.add(doc1);
        assertThat(ur.getStatus(), is(SUCCESS));
        server.commit();

        QueryResponse response1 = server.query(new SolrQuery("*:*"));
        assertThat(response1.getResults().getNumFound(), is(1L));

        QueryResponse response2 = server.query(new SolrQuery("something_txt:*wombat*"));
        assertThat(response2.getResults().getNumFound(), is(1L));
    }

    private void removeIndexDirectory() throws IOException {
        File indexDir = new File(indexLocation, "data/index");
        FileUtils.deleteDirectory(indexDir);
    }
}

My POM has the following dependencies:

<properties>
    <solr.version>3.6.0</solr.version>
    <httpcomponents.version>4.3.2</httpcomponents.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.apache.solr</groupId>
        <artifactId>solr-solrj</artifactId>
        <version>${solr.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.solr</groupId>
        <artifactId>solr-core</artifactId>
        <version>${solr.version}</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>${httpcomponents.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpmime</artifactId>
        <version>${httpcomponents.version}</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.6.1</version>
    </dependency>
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.4</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.11</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.hamcrest</groupId>
        <artifactId>hamcrest-library</artifactId>
        <version>1.3</version>
        <scope>test</scope>
    </dependency>
</dependencies>

I've set up a separate project to keep all my Solr config in and run tests against it. The directory structure is:

solr-test
|--src
|  |--test
|--tomcat7
`  |--apps
      |--apache-solr-3.6.0
         |--conf
         |--data
            |--index

This seems to work well for me. This set up will also let you write tests using HttpSolrServer to test a remote server's schema.

Also, note the server.commit() call in the middle of the test. This needs to be there otherwise the Solr transaction isn't complete and the new document won't be visible.



回答3:

I'm using https://github.com/moliware/travis-solr for my tests, maybe it's useful for you too.