简体   繁体   中英

[qaf]how to integrate with spring when I use testng xml to run cucumber test case

I use qaf with testng to run cucumber test case. Now I want use spring to autowired UserRepository in test step.

<suite name="Web Demo Suite" verbose="0" parallel="tests" thread-count="100">
    <listeners>
        <listener class-name="com.quantum.listeners.QuantumReportiumListener" />
    </listeners>
    <test name="Web Test" enabled="true" thread-count="10">
        <groups>
            <run>
                <include name="@testH2Spring"/>
            </run>
        </groups>
        <classes>
            <class name="com.qmetry.qaf.automation.step.client.gherkin.GherkinScenarioFactory" />
        </classes>
    </test>
</suite>

Below is the feature file:

  @testH2Spring
  Scenario: H2 Spring test
    When I control with DB by Spring

Below is the JPA config:

@Configuration
@EnableJpaRepositories(basePackages = "com.quantum.repository")
public class H2DBConfig {

    @Bean
    public ComboPooledDataSource datasource() throws PropertyVetoException {

        String path = System.getProperty("user.dir");
        System.out.println(path);

        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setDriverClass("org.h2.Driver");
        dataSource.setJdbcUrl("jdbc:h2:file:" + path + "/src/main/resources/data/test");
        dataSource.setUser("sa");
        dataSource.setPassword("");
        dataSource.setInitialPoolSize(5);
        dataSource.setMaxPoolSize(10);
        return dataSource;
    }

    @Bean
    public JpaVendorAdapter jpaVendorAdapter() {
        HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
        adapter.setDatabase(Database.H2);
        adapter.setShowSql(true);
        adapter.setGenerateDdl(true);
        adapter.setDatabasePlatform("org.hibernate.dialect.H2Dialect");

        return adapter;
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource, JpaVendorAdapter jpaVendorAdapter){

        LocalContainerEntityManagerFactoryBean  entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
        entityManagerFactoryBean.setDataSource(dataSource);
        entityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter);
        entityManagerFactoryBean.setPackagesToScan("com.quantum.entity");
        return entityManagerFactoryBean;
    }

    @Bean
    public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
        return new JpaTransactionManager(emf);
    }

    @Bean
    public BeanPostProcessor persistenceTranslation() {
        return new PersistenceExceptionTranslationPostProcessor();
    }

}

Below is the userRepository

@Repository
public interface UserRepository extends JpaRepository<User, Integer> {}

Below is the test step:

@QAFTestStepProvider
@ContextConfiguration(classes = H2DBConfig.class)
public class WebTestSteps extends AbstractTestNGSpringContextTests {

    private UserRepository userRepository;

    @Autowired
    public void setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @When("^I open browser to web page$")
    public void iOpenBrowserToWebPage() {

        User user = userRepository.getOne(1);
        System.out.println(user.toString());
    }

}

If I use testng xml to run cucumber test case like above, the UserRepository can't @Autowired successfully.

how to solve it so that the UserRepository can be @Autowired?

To invoke any TestStep QAF requires object of that class or method needs to be a static. By default QAF creates a new object using non args constructor.

But in QAF you can set your CustomObjectFactory by using below method. You can set your object factory in your TestNG Listeners.

ObjectFactory.INSTANCE.setFactory(new CustomObjectFactory());
import com.qmetry.qaf.automation.step.ObjectFactory;

public class CustomObjectFactory implements ObjectFactory {

    @Override
    public <T> T getObject(Class<T> cls) throws Exception {
        // your implementation
        return object;
    }

}

Here you can have your implementation to create object of that class. Hope this helps.

EDIT : If you want to use any third party Object factory you can use it. Foe exmaple, below is using basic Guice implementation.

/**
 * @author chirag.jayswal
 *
 */
public class GuiceObjectFactory extends DefaultObjectFactory {//implements ObjectFactory {
    private static final Injector injector = Guice.createInjector(new GuiceModule());
    public <T> T getObject(Class<T> cls) throws Exception {
        T obj = injector.getInstance(cls);
        return obj;
    }
}

Make sure that you have other configuration related to underlying object factory.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM