A/B test options at the widget level [closed]

This is quite easy using the sidebars_widget filter.

What we want to do is, in the back end, add our three widgets in the desired sidebar where we need them. This will, as always, display all the widgets in the order they appear in the backend in the sidebar.

If you only need this on the homepage, it is really wise registering a sidebar and then conditionally (is_home()) includes it in your template.

Anyways, we will now use the sidebars_widget filter to randomly remove two of the three sidebars we have added. This will leave you with a random single widget. It must however be noted, you might have the same widget displaying on a new page load as anything random cannot be controlled. Out of three numbers, choosing two randomly, there will always be the possibility that the same two numbers might be chosen again. If you need more control over this, you would need to alter that specific piece of code and somehow implement another more reliable system to handle this

Here is the code, I have commented it so you can follow it easily and also modify as needed. Just note, change sidebar-2 to the exact ID of the sidebar you need to target

add_filter( 'sidebars_widgets', function ( $sidebars_widgets )
{
    // Return our filter when we are on admin screen
    if ( is_admin() )
        return $sidebars_widgets;

    /**
     * We only want to target only the homepage, so return if it is not homepage
     * You would want to register the sidebar also only on the homepage, otherwise you would
     * need to extend the function to remove the widgets on any other page
     */
    if ( !is_home() )
        return $sidebars_widgets;

    // The ID of the sidebar you want to target
    $sidebar_id_to_target="sidebar-2";

    foreach ( $sidebars_widgets as $key=>$sidebars_widget ) {
        // Skip a sidebar if it it isn't our $sidebar_id_to_target
        if ( $key != $sidebar_id_to_target )
            continue;

        // Count the amount of widgets in the desired sidebar
        $counter = count( $sidebars_widget );

        // If the count is 0 or 1, return early
        if ( $counter <= 1 )
            break;

        /**
         * We now want to select a random widget, which will be a random array key
         * We would also need to unset the other two
         */
        $random_numbers = array_rand( range( 0, ( $counter - 1 ) ), ( $counter - 1 ) );
        foreach ( $random_numbers as $random_number )
            unset( $sidebars_widgets[$sidebar_id_to_target][$random_number] );
    }

    return $sidebars_widgets;
});