Tag Archives: test

Thumbnail

How To Improve Test Coverage For Your Android App Using Mockito And Espresso




How To Improve Test Coverage For Your Android App Using Mockito And Espresso

Vivek Maskara



In app development, a variety of use cases and interactions come up as one iterates the code. The app might need to fetch data from a server, interact with the device’s sensors, access local storage or render complex user interfaces.

The important thing to consider while writing tests is the units of responsibility that emerge as you design the new feature. The unit test should cover all possible interactions with the unit, including standard interactions and exceptional scenarios.

In this article, we will cover the fundamentals of testing and frameworks such as Mockito and Espresso, which developers can use to write unit tests. I will also briefly discuss how to write testable code. I’ll also explain how to get started with local and instrumented tests in Android.

Recommended reading: How To Set Up An Automated Testing System Using Android Phones (A Case Study)

Fundamentals Of Testing

A typical unit test contains three phases.

  1. First, the unit test initializes a small piece of an application it wants to test.
  2. Then, it applies some stimulus to the system under test, usually by calling a method on it.
  3. Finally, it observes the resulting behavior.

If the observed behavior is consistent with the expectations, the unit test passes; otherwise, it fails, indicating that there is a problem somewhere in the system under test. These three unit test phases are also known as arrange, act and assert, or simply AAA. The app should ideally include three categories of tests: small, medium and large.

  • Small tests comprise unit tests that mock every major component and run quickly in isolation.
  • Medium tests are integration tests that integrate several components and run on emulators or real devices.
  • Large tests are integration and UI tests that run by completing a UI workflow and ensure that the key end-user tasks work as expected.

Note: An instrumentation test is a type of integration test. These are tests that run on an Android device or emulator. These tests have access to instrumentation information, such as the context of the app under test. Use this approach to run unit tests that have Android dependencies that mock objects cannot easily satisfy.

Writing small tests allows you to address failures quickly, but it’s difficult to gain confidence that a passing test will allow your app to work. It’s important to have tests from all categories in the app, although the proportion of each category can vary from app to app. A good unit test should be easy to write, readable, reliable and fast.

Here’s a brief introduction to Mockito and Espresso, which make testing Android apps easier.

Mockito

There are various mocking frameworks, but the most popular of them all is Mockito:

Mockito is a mocking framework that tastes really good. It lets you write beautiful tests with a clean & simple API. Mockito doesn’t give you hangover because the tests are very readable and they produce clean verification errors.

Its fluent API separates pre-test preparation from post-test validation. Should the test fail, Mockito makes it clear to see where our expectations differ from reality! The library has everything you need to write complete tests.

Espresso

Espresso helps you write concise, beautiful and reliable Android UI tests.

The code snippet below shows an example of an Espresso test. We will take up the same example later in this tutorial when we talk in detail about instrumentation tests.

@Test
public void setUserName() 
    onView(withId(R.id.name_field)).perform(typeText("Vivek Maskara"));
    onView(withId(R.id.set_user_name)).perform(click());
    onView(withText("Hello Vivek Maskara!")).check(matches(isDisplayed()));

Espresso tests state expectations, interactions and assertions clearly, without the distraction of boilerplate content, custom infrastructure or messy implementation details getting in the way. Whenever your test invokes onView(), Espresso waits to perform the corresponding UI action or assertion until the synchronization conditions are met, meaning:

  • the message queue is empty,
  • no instances of AsyncTask are currently executing a task,
  • the idling resources are idle.

These checks ensure that the test results are reliable.

Writing Testable Code

Unit testing Android apps is difficult and sometimes impossible. A good design, and only a good design, can make unit testing easier. Here are some of the concepts that are important for writing testable code.

Avoid Mixing Object Graph Construction With Application Logic

In a test, you want to instantiate the class under test and apply some stimulus to the class and assert that the expected behavior was observed. Make sure that the class under test doesn’t instantiate other objects and that those objects do not instantiate more objects and so on. In order to have a testable code base, your application should have two kinds of classes:

  • The factories, which are full of the “new” operators and which are responsible for building the object graph of your application;
  • The application logic classes, which are devoid of the “new” operator and which are responsible for doing the work.

Constructors Should Not Do Any Work

The most common operation you will do in tests is the instantiation of object graphs. So, make it easy on yourself, and make the constructors do no work other than assigning all of the dependencies into the fields. Doing work in the constructor not only will affect the direct tests of the class, but will also affect related tests that try to instantiate your class indirectly.

Avoid Static Methods Wherever Possible

The key to testing is the presence of places where you can divert the normal execution flow. Seams are needed so that you can isolate the unit of test. If you build an application with nothing but static methods, you will have a procedural application. How much a static method will hurt from a testing point of view depends on where it is in your application call graph. A leaf method such as Math.abs() is not a problem because the execution call graph ends there. But if you pick a method in a core of your application logic, then everything behind the method will become hard to test, because there is no way to insert test doubles

Avoid Mixing Of Concerns

A class should be responsible for dealing with just one entity. Inside a class, a method should be responsible for doing just one thing. For example, BusinessService should be responsible just for talking to a Business and not BusinessReceipts. Moreover, a method in BusinessService could be getBusinessProfile, but a method such as createAndGetBusinessProfile would not be ideal for testing. SOLID design principles must be followed for good design:

  • S: single-responsibility principle;
  • O: open-closed principle;
  • L: Liskov substitution principle;
  • I: interface segregation principle;
  • D: dependency inversion principle.

In the next few sections, we will be using examples from a really simple application that I built for this tutorial. The app has an EditText that takes a user name as input and displays the name in a TextView upon the click of a button. Feel free to take the complete source code for the project from GitHub. Here’s a screenshot of the app:


Testing example


Large preview

Writing Local Unit Tests

Unit tests can be run locally on your development machine without a device or an emulator. This testing approach is efficient because it avoids the overhead of having to load the target app and unit test code onto a physical device or emulator every time your test is run. In addition to Mockito, you will also need to configure the testing dependencies for your project to use the standard APIs provided by the JUnit 4 framework.

Setting Up The Development Environment

Start by adding a dependency on JUnit4 in your project. The dependency is of the type testImplementation, which means that the dependencies are only required to compile the test source of the project.

testImplementation 'junit:junit:4.12'

We will also need the Mockito library to make interaction with Android dependencies easier.

testImplementation "org.mockito:mockito-core:$MOCKITO_VERSION"

Make sure to sync the project after adding the dependency. Android Studio should have created the folder structure for unit tests by default. If not, make sure the following directory structure exists:

<Project Dir>/app/src/test/java/com/maskaravivek/testingExamples

Creating Your First Unit Test

Suppose you want to test the displayUserName function in the UserService. For the sake of simplicity, the function simply formats the input and returns it back. In a real-world application, it could make a network call to fetch the user profile and return the user’s name.

@Singleton
class UserService @Inject
constructor(private var context: Context) 
    
    fun displayUserName(name: String): String 
        val userNameFormat = context.getString(R.string.display_user_name)
        return String.format(Locale.ENGLISH, userNameFormat, name)
    
}

We will start by creating a UserServiceTest class in our test directory. The UserService class uses Context, which needs to be mocked for the purpose of testing. Mockito provides a @Mock notation for mocking objects, which can be used as follows:

@Mock internal var context: Context? = null

Similarly, you’ll need to mock all dependencies required to construct the instance of the UserService class. Before your test, you’ll need to initialize these mocks and inject them into the UserService class.

  • @InjectMock creates an instance of the class and injects the mocks that are marked with the annotations @Mock into it.
  • MockitoAnnotations.initMocks(this); initializes those fields annotated with Mockito annotations.

Here’s how it can be done:

class UserServiceTest 
    
    @Mock internal var context: Context? = null
    @InjectMocks internal var userService: UserService? = null
    
    @Before
    fun setup() 
        MockitoAnnotations.initMocks(this)
    
}

Now you are done setting up your test class. Let’s add a test to this class that verifies the functionality of the displayUserName function. Here’s what the test looks like:

@Test
fun displayUserName() 
    doReturn("Hello %s!").`when`(context)!!.getString(any(Int::class.java))
    val displayUserName = userService!!.displayUserName("Test")
    assertEquals(displayUserName, "Hello Test!")

The test uses a doReturn().when() statement to provide a response when a context.getString() is invoked. For any input integer, it will return the same result, "Hello %s!". We could have been more specific by making it return this response only for a particular string resource ID, but for the sake of simplicity, we are returning the same response to any input.
Finally, here’s what the test class looks like:

class UserServiceTest 
    @Mock internal var context: Context? = null
    @InjectMocks internal var userService: UserService? = null
    @Before
    fun setup() 
        MockitoAnnotations.initMocks(this)
    
     
    @Test
    fun displayUserName() 
        doReturn("Hello %s!").`when`(context)!!.getString(any(Int::class.java))
        val displayUserName = userService!!.displayUserName("Test")
        assertEquals(displayUserName, "Hello Test!")
    
}

Running Your Unit Tests

In order to run the unit tests, you need to make sure that Gradle is synchronized. In order to run a test, click on the green play icon in the IDE.




making sure that Gradle is synchronized

When the unit tests are run, successfully or otherwise, you should see this in the “Run” menu at the bottom of the screen:

result after unit tests are run
Large preview

You are done with your first unit test!

Writing Instrumentation Tests

Instrumentation tests are most suited for checking values of UI components when an activity is run. For instance, in the example above, we want to make sure that the TextView shows the correct user name after the Button is clicked. They run on physical devices and emulators and can take advantage of the Android framework APIs and supporting APIs, such as the Android Testing Support Library.
We’ll use Espresso to take actions on the main thread, such as button clicks and text changes.

Setting Up The Development Environment

Add a dependency on Espresso:

androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'

Instrumentation tests are created in an androidTest folder.

<Project Dir>/app/src/androidTest/java/com/maskaravivek/testingExamples

If you want to test a simple activity, create your test class in the same package as your activity.

Creating Your First Instrumentation Test

Let’s start by creating a simple activity that takes a name as input and, on the click of a button, displays the user name. The code for the activity above is quite simple:

class MainActivity : AppCompatActivity() 
    
    var button: Button? = null
    var userNameField: EditText? = null
    var displayUserName: TextView? = null
    
    override fun onCreate(savedInstanceState: Bundle?) 
        super.onCreate(savedInstanceState)
        AndroidInjection.inject(this)
        setContentView(R.layout.activity_main)
        initViews()
    
    
    private fun initViews() 
        button = this.findViewById(R.id.set_user_name)
        userNameField = this.findViewById(R.id.name_field)
        displayUserName = this.findViewById(R.id.display_user_name)
    
        this.button!!.setOnClickListener(
            displayUserName!!.text = "Hello $userNameField!!.text!"
        })
    }
}

To create a test for the MainActivity, we will start by creating a MainActivityTest class under the androidTest directory. Add the AndroidJUnit4 annotation to the class to indicate that the tests in this class will use the default Android test runner class.

@RunWith(AndroidJUnit4::class)
class MainActivityTest {}

Next, add an ActivityTestRule to the class. This rule provides functional testing of a single activity. For the duration of the test, you will be able to manipulate your activity directly using the reference obtained from getActivity().

@Rule @JvmField var activityActivityTestRule = ActivityTestRule(MainActivity::class.java)

Now that you are done setting up the test class, let’s add a test that verifies that the user name is displayed by clicking the “Set User Name” button.

@Test
fun setUserName() 
    onView(withId(R.id.name_field)).perform(typeText("Vivek Maskara"))
    onView(withId(R.id.set_user_name)).perform(click())
    onView(withText("Hello Vivek Maskara!")).check(matches(isDisplayed()))

The test above is quite simple to follow. It first simulates some text being typed in the EditText, performs the click action on the button, and then checks whether the correct text is displayed in the TextView.

The final test class looks like this:

@RunWith(AndroidJUnit4::class)
class MainActivityTest 
    
    @Rule @JvmField var activityActivityTestRule = ActivityTestRule(MainActivity::class.java)
    
    @Test
    fun setUserName() 
        onView(withId(R.id.name_field)).perform(typeText("Vivek Maskara"))
        onView(withId(R.id.set_user_name)).perform(click())
        onView(withText("Hello Vivek Maskara!")).check(matches(isDisplayed()))
    
}

Running Your Instrumentation Tests

Just like for unit tests, click on the green play button in the IDE to run the test.


clicking on the green play button in IDE to run the test


Large preview

Upon a click of the play button, the test version of the app will be installed on the emulator or device, and the test will run automatically on it.




Large preview

Intrumentation Testing Using Dagger, Mockito, And Espresso

Espresso is one of the most popular UI testing frameworks, with good documentation and community support. Mockito ensures that objects perform the actions that are expected of them. Mockito also works well with dependency-injection libraries such as Dagger. Mocking the dependencies allows us to test a scenario in isolation.
Until now, our MainActivity hasn’t used any dependency injection, and, as a result, we were able to write our UI test very easily. To make things a bit more interesting, let’s inject UserService in the MainActivity and use it to get the text to be displayed.

class MainActivity : AppCompatActivity() 
    
    var button: Button? = null
    var userNameField: EditText? = null
    var displayUserName: TextView? = null
    
    @Inject lateinit var userService: UserService
    
    override fun onCreate(savedInstanceState: Bundle?) 
        super.onCreate(savedInstanceState)
        AndroidInjection.inject(this)
        setContentView(R.layout.activity_main)
        initViews()
    
    
    private fun initViews() 
        button = this.findViewById(R.id.set_user_name)
        userNameField = this.findViewById(R.id.name_field)
        displayUserName = this.findViewById(R.id.display_user_name)
    
        this.button!!.setOnClickListener(
            displayUserName!!.text = userService.displayUserName(userNameField!!.text.toString())
        )
    }
}

With Dagger in the picture, we will have to set up a few things before we write instrumentation tests.
Imagine that the displayUserName function internally uses some API to fetch the details of the user. There should not be a situation in which a test does not pass due to a server fault. To avoid such a situation, we can use the dependency-injection framework Dagger and, for networking, Retrofit.

Setting Up Dagger In The Application

We will quickly set up the basic modules and components required for Dagger. If you are not
familiar with Dagger, check out Google’s documentation on it. We will start adding dependencies for using Dagger in the build.gradle file.

implementation "com.google.dagger:dagger-android:$DAGGER_VERSION"
implementation "com.google.dagger:dagger-android-support:$DAGGER_VERSION"
implementation "com.google.dagger:dagger:$DAGGER_VERSION"
kapt "com.google.dagger:dagger-compiler:$DAGGER_VERSION"
kapt "com.google.dagger:dagger-android-processor:$DAGGER_VERSION"

Create a component in the Application class, and add the necessary modules that will be used in our project. We need to inject dependencies in the MainActivity of our app. We will add a @Module for injecting in the activity.

@Module
abstract class ActivityBuilder 
    @ContributesAndroidInjector
    internal abstract fun bindMainActivity(): MainActivity

The AppModule class will provide the various dependencies required by the application. For our example, it will just provide an instance of Context and UserService.

@Module
open class AppModule(val application: Application) 
    @Provides
    @Singleton
    internal open fun provideContext(): Context 
        return application
    
    
    @Provides
    @Singleton
    internal open fun provideUserService(context: Context): UserService 
        return UserService(context)
    
}

The AppComponent class lets you build the object graph for the application.

@Singleton
@Component(modules = [(AndroidSupportInjectionModule::class), (AppModule::class), (ActivityBuilder::class)])
interface AppComponent 
    
    @Component.Builder
    interface Builder 
        fun appModule(appModule: AppModule): Builder
        fun build(): AppComponent
    
    
    fun inject(application: ExamplesApplication)
}

Create a method that returns the already built component, and then inject this component into onCreate().

open class ExamplesApplication : Application(), HasActivityInjector 
    @Inject lateinit var dispatchingActivityInjector: DispatchingAndroidInjector<Activity>
    
    override fun onCreate() 
        super.onCreate()
        initAppComponent().inject(this)
    
    
    open fun initAppComponent(): AppComponent 
        return DaggerAppComponent
            .builder()
            .appModule(AppModule(this))
            .build()
    
    
    override fun activityInjector(): DispatchingAndroidInjector<Activity>? 
        return dispatchingActivityInjector
    
}

Setting Up Dagger In The Test Application

In order to mock responses from the server, we need to create a new Application class that extends the class above.

class TestExamplesApplication : ExamplesApplication() 
    
    override fun initAppComponent(): AppComponent 
        return DaggerAppComponent.builder()
            .appModule(MockApplicationModule(this))
            .build()
    
    
    @Module
    private inner class MockApplicationModule internal constructor(application: Application) : AppModule(application) 
        override fun provideUserService(context: Context): UserService 
            val mock = Mockito.mock(UserService::class.java)
            `when`(mock!!.displayUserName("Test")).thenReturn("Hello Test!")
            return mock
        
    }
}

As you can see in the example above, we’ve used Mockito to mock UserService and assume the results. We still need a new runner that will point to the new application class with the overwritten data.

class MockTestRunner : AndroidJUnitRunner() 
    
    override fun onCreate(arguments: Bundle) 
        StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.Builder().permitAll().build())
        super.onCreate(arguments)
    
    
    @Throws(InstantiationException::class, IllegalAccessException::class, ClassNotFoundException::class)
    override fun newApplication(cl: ClassLoader, className: String, context: Context): Application 
        return super.newApplication(cl, TestExamplesApplication::class.java.name, context)
    
}

Next, you need to update the build.gradle file to use the MockTestRunner.

android 
    ...
    
    defaultConfig 
        ...
        testInstrumentationRunner ".MockTestRunner"
    
}

Running The Test

All tests with the new TestExamplesApplication and MockTestRunner should be added at androidTest package. This implementation makes the tests fully independent from the server and gives us the ability to manipulate responses.
With the setup above in place, our test class won’t change at all. When the test is run, the app will use TestExamplesApplication instead of ExamplesApplication, and, thus, a mocked instance of UserService will be used.

@RunWith(AndroidJUnit4::class)
class MainActivityTest 
    @Rule @JvmField var activityActivityTestRule = ActivityTestRule(MainActivity::class.java)
    
    @Test
    fun setUserName() 
        onView(withId(R.id.name_field)).perform(typeText("Test"))
        onView(withId(R.id.set_user_name)).perform(click())
        onView(withText("Hello Test!")).check(matches(isDisplayed()))
    
}

The test will run successfully when you click on the green play button in the IDE.


successfully setting up Dagger and run tests using Espresso and Mockito


Large preview

That’s it! You have successfully set up Dagger and run tests using Espresso and Mockito.

Conclusion

We’ve highlighted that the most important aspect of improving code coverage is to write testable code. Frameworks such as Espresso and Mockito provide easy-to-use APIs that make writing tests for various scenarios easier. Tests should be run in isolation, and mocking the dependencies gives us an opportunity to ensure that objects perform the actions that are expected of them.

A variety of Android testing tools are available, and, as the ecosystem matures, the process of setting up a testable environment and writing tests will become easier.

Writing unit tests requires some discipline, concentration and extra effort. By creating and running unit tests against your code, you can easily verify that the logic of individual units is correct. Running unit tests after every build helps you to quickly catch and fix software regressions introduced by code changes to your app. Google’s testing blog discusses the advantages of unit testing.
The complete source code for the examples used in this article is available on GitHub. Feel free to take a look at it.

Smashing Editorial
(da, lf, ra, al, il)


Link:  

How To Improve Test Coverage For Your Android App Using Mockito And Espresso

Thumbnail

Tripwire Marketing: Lure in More Customers With 12 Slam-Dunk Tripwire Ideas

tripwire marketing

You’re unhappy with your conversion rate. People just aren’t buying what you’re selling. The solution might lie in tripwire marketing. The term tripwire marketing might sound a little shady, like you’re trying to get one over on your customer. That’s not the case at all. Marketing and advertising experts have been using tripwire marketing for decades in one form or another, and it works just as well online as it does in brick-and-mortar sales. In fact, it’s even more effective because you can more easily stay in touch with the customer. What is tripwire marketing? And how does it work?…

The post Tripwire Marketing: Lure in More Customers With 12 Slam-Dunk Tripwire Ideas appeared first on The Daily Egg.

Follow this link:  

Tripwire Marketing: Lure in More Customers With 12 Slam-Dunk Tripwire Ideas

Thumbnail

How to do A/B Testing and Improve Your Conversions Quickly

ab-testing-5

If you’re not A/B testing your content, you’re leaving money on the table. The only way to truly evaluate your conversion funnel and marketing campaign is to get data directly from your customers. From e-commerce to SaaS, guesswork won’t cut it. You need enough hard data to understand how your audience responds to specific elements on your website. But what is A/B testing and how does it work? That’s what I’m covering today. There’s a lot of information here, so feel free to skip around if there’s a specific section that interests you: What Is A/B Testing and How Does…

The post How to do A/B Testing and Improve Your Conversions Quickly appeared first on The Daily Egg.

View original article: 

How to do A/B Testing and Improve Your Conversions Quickly

Thumbnail

The 13 Most Effective Ways to Increase your Conversion Rate

increase conversion rate 2018

The average conversion rate for a Facebook Ad is 9.1 percent. Website conversion rates, though, lag at an average of just 2.35 percent. The data varies by industry. On Facebook, for instance, fitness ads top the charts at nearly 15 percent. You might be surprised to learn that B2B ads convert at an impressive 10.63 percent. But what if you don’t want to spend hundreds or thousands of dollars on Facebook Ads? You’d rather increase conversion rate on your own website through organic marketing. That’s certainly possible. I’ve done it myself. But you need some information before you can start…

The post The 13 Most Effective Ways to Increase your Conversion Rate appeared first on The Daily Egg.

Link: 

The 13 Most Effective Ways to Increase your Conversion Rate

3 Assumptions That Can Kill Conversions

It’s dangerous territory to make assumptions, over-generalize, or depend on logic or even so called “best practices” to make decisions about site changes. My team and I launched an e-commerce website a few years ago, and here are four ways we tried to break through common conversion pitfalls in order to ensure we increased our own conversions: Assumption #1 – All Of Your Ideas Are Great Ideas You’ve had these experiences countless times… you had a great idea for the site that was informed and re-enforced by “best practices.” You sold it to the team by explaining how your idea…

The post 3 Assumptions That Can Kill Conversions appeared first on The Daily Egg.

See original: 

3 Assumptions That Can Kill Conversions

Hypothesis Testing

hypothesis testing

Hypothesis Testing: A systematic way to select samples from a group or population with the intent of making a determination about the expected behavior of the entire group. Part of the field of inferential statistics, hypothesis testing is also known as significance testing, since significance (or lack of same) is usually the bar that determines whether or not the hypothesis is accepted. A hypothesis is similar to a theory If you believe something might be true but don’t yet have definitive proof, it is considered a theory until that proof is provided. Turning theories into accepted statements of fact is…

The post Hypothesis Testing appeared first on The Daily Egg.

Continue reading here: 

Hypothesis Testing

10 Simple Tips To Improve User Testing

(This is a sponsored post). Testing is a fundamental part of the UX designer’s job and a core part of the overall UX design process. Testing provides the inspiration, guidance and validation that product teams need in order to design great products. That’s why the most effective teams make testing a habit.
Usability testing involves observing users as they use a product. It helps you find where users struggle and what they like.

Excerpt from: 

10 Simple Tips To Improve User Testing

The Crazy Egg Guide to Landing Page Optimization

When it comes to increasing conversion rates, few strategies are more effective than the implementation of landing pages. Yet, these crucial linchpins to the optimization process are often rushed or overlooked completely in the grand scheme of marketing. Here at Crazy Egg, we believe it’s past time to give these hard-working pages a little more attention, which is why we’ve created this complete guide to landing page optimization. Even if you consider yourself a landing page pro, you’ll want to read this guide to make sure your pages are on track and converting as well as they should be. Why…

The post The Crazy Egg Guide to Landing Page Optimization appeared first on The Daily Egg.

Link to original: 

The Crazy Egg Guide to Landing Page Optimization

[Case Study] Ecwid sees 21% lift in paid plan upgrades in one month

Reading Time: 2 minutes

What would you do with 21% more sales this month?

I bet you’d walk into your next meeting with your boss with an extra spring in your step, right?

Well, when you implement a strategic marketing optimization program, results like this are not only possible, they are probable.

In this new case study, you’ll discover how e-commerce software supplier, Ecwid, ran one experiment for four weeks, and saw a 21% increase in paid upgrades.

Get the full Ecwid case study now!

Download a PDF version of the Ecwid case study, featuring experiment details, supplementary takeaways and insights, and a testimonial from Ecwid’s Sr. Director, Digital Marketing.



By entering your email, you’ll receive bi-weekly WiderFunnel Blog updates and other resources to help you become an optimization champion.

A little bit about Ecwid

Ecwid provides easy-to-use online store setup, management, and payment solutions. The company was founded in 2009, with the goal of enabling business-owners to add online stores to their existing websites, quickly and without hassle.

The company has a freemium business model: Users can sign up for free, and unlock more features as they upgrade to paid packages.

Ecwid’s partnership with WiderFunnel

In November 2016, Ecwid partnered with WiderFunnel with two primary goals:

  1. To increase initial signups for their free plan through marketing optimization, and
  2. To increase the rate of paid upgrades, through platform optimization

This case study focuses on a particular experiment cycle that ran on Ecwid’s step-by-step onboarding wizard.

The methodology

Last Winter, the WiderFunnel Strategy team did an initial LIFT Analysis of the onboarding wizard, and identified several potential barriers to conversion. (Both in terms of completing steps to setup a new store, and in terms of upgrading to a paid plan.)

The lead WiderFunnel Strategist for Ecwid, Dennis Pavlina, decided to create an A/B cluster test to 1) address the major barriers simultaneously, and 2) to get major lift for Ecwid, quickly.

The overarching goal was to make the onboarding process smoother. The WiderFunnel and Ecwid optimization teams hoped that enhancing the initial user experience, and exposing users to the wide range of Ecwid’s features, would result in more users upgrading to paid plans.

Dennis Pavlina

Ecwid’s two objectives ended up coming together in this test. We thought that if more new users interacted with the wizard and were shown the whole ‘Ecwid world’ with all the integrations and potential it has, they would be more open to upgrading. People needed to be able to see its potential before they would want to pay for it.

Dennis Pavlina, Optimization Strategist, WiderFunnel

The Results

This experiment ran for four weeks, at which point the variation was determined to be the winner with 98% confidence. The variation resulted in a 21.3% increase in successful paid account upgrades for Ecwid.

Read the full case study for:

  • The details on the initial barriers to conversion
  • How this test was structured
  • Which secondary metrics we tracked, and
  • The supplementary takeaways and customer insights that came from this test

The post [Case Study] Ecwid sees 21% lift in paid plan upgrades in one month appeared first on WiderFunnel Conversion Optimization.

See original article:

[Case Study] Ecwid sees 21% lift in paid plan upgrades in one month

How to Create, Track and Rank CRO Hypotheses So You Know What to Test

CRO hypothesis ranking

CRO makes big promises. But the way people get to those 300% lifts in conversions is by being organized. Otherwise, you find yourself in the position that a lot of marketers do: you do a test, build on the result, wait a while, do another test, wait a while… meanwhile, the big jumps in conversions, leads and revenue never really seem to manifest. That’s because only a structured approach can get you in position to make the best use of your testing time and budget. This isn’t something you want to be doing by the seat of your pants. In…

The post How to Create, Track and Rank CRO Hypotheses So You Know What to Test appeared first on The Daily Egg.

Follow this link:

How to Create, Track and Rank CRO Hypotheses So You Know What to Test