Tests to make sure the migration was successful

In the migration process, how can we test our website after the process to make sure everything has been migrated 100% correctly?
I am not talking about screening by my eye, but several tests to be sure everything is fine and all files and code are migrated.
I am asking as some hosting providers (like Closte, Guru UK, etc.) after the process of migration, says “Complete” with several steps and tests.
I need to provide my clients with something professional. Please advice.

  • Dimitris
    • Support Star

    Hello there Mohamed

    This sounds like a nice addition. We recently had a similar request for the Snapshot plugin.
    I’ve already shared this with our sysadmins for further consideration, as I’m not sure how difficult such implementation can be.
    We’ll keep you posted here as soon as there’s any development on this.

    Thank you,

  • Nastia
    • Support Rock Star

    Hello Mohamed

    I hope you’re doing well!

    When our sys-admins migrating a site to our hosting, they do the proper tests that confirm that the migration was successful. This is done mostly via the SSH command line and a test report from there is not available on our hosting front end.

    I’m afraid there are no tutorials that will provide this information. The migration check-list should go like this:
    – First backup your original site
    – After the migration done, please check for Brocken links on your site, to make sure none of the links on your site have issues. You may use this plugin:
    – Enable WordPress debug mode, to track any errors that may occur. To do so, add the following lines in the wp-config.php file

    define( 'WP_DEBUG', true );
    define( 'WP_DEBUG_LOG', true );
    define( 'WP_DEBUG_DISPLAY', false );

    If there are files missing, the debug.log file that will be saved in /wp-content/ folder will show missing files errors.

    To ensure that all is working well
    – After a migration tests the new site by opening all pages and posts. Try to login and logout. If you have Woocommerce plugin check if purchase working well
    – Create a test post and page
    – Upload a media file

    Please feel free as well to have a look at these blog posts:

    Hope this helps!

    Kind regards,

  • Pawel
    • Staff

    Hello Mohamed !
    Here’s a procedure I usually follow when checking if a backup was restored successfully (especially in cases where the restoration process gave an error, but the site seems to be fine).

    This is for comparing backups, but you can use the backup created before migration to compare the files after a migration.

    This procedure does require SSH access and requires some knowledge of linux terminal.

    There’s one additional issue when doing those checks – you need to be sure that the backup is correct and has all the files, else this will not give you correct results. But if the backup was created without any errors, it should be okay to use for comparing.

    0. Use staging

    If possible, create a staging environment to do this.

    1. Create a SSH user and log in

    Head to the droplet’s admin dash and create a new SSH user. Log in using ssh:
    ssh username@siteid.wpmudev.host

    2. Preparing the backup files for work

    Create a new directory:

    mkdir site/backup
    cd site/backup

    Upload the backup file to that directory. To do this via SSH from your computer, you can run:
    scp full_backup-1569252782-full-17806545.zip username@siteid.wpmudev.host:/site/backup/
    You can also use SFTP or if the backup is publicly available, you can grab it with wget from inside the droplet itself:
    wget https://somehost.com/full_backup-1569252782-full-17806545.zip
    Unzip the backup:
    unzip full_backup-1569252782-full-17806545.zip
    You should have some *.sql files and a www directory with the site files ready.

    3. Comparing files

    We don’t have diff command available on our hosts, but we can use git diff to do the file comparison instead:
    git diff --no-index --name-status --output=diff.txt www ~/site/public_html/
    This will create a diff.txt file that will contain all the differences. It may take a bit to run this command, usually a minute or so, depending on the size of the site. There should be no output during that time.
    Run some sed to clean up files that aren’t important (HB caches and snapshots):
    sed -i -e "\;wphb-cache;d" -e "\;wp-content/uploads/snapshot;d" ./diff.txt
    The diff.txt should now look something like this:

     A       /home/pawe/site/public_html/1.html
     A       /home/pawe/site/public_html/snapshot-installer-0.1.4.php
     M       www/wp-config.php
     D       www/wp-content/languages/plugins/jetpack-en_AU-6030814ecc6554f776e6c2f913459ba8.json
     D       www/wp-content/languages/plugins/jetpack-en_AU-e48297939dadcf2a16dec6bb472204f5.json
     D       www/wp-content/languages/plugins/jetpack-en_AU-f2b234a1eb36d7500074cd58bfbd9b1c.json
     D       www/wp-content/languages/plugins/jetpack-en_AU.mo
     D       www/wp-content/languages/plugins/jetpack-en_AU.po
     D       www/wp-content/languages/plugins/updraftplus-en_AU.mo
     D       www/wp-content/languages/plugins/updraftplus-en_AU.po
     D       www/wp-content/languages/plugins/wordpress-importer-en_AU.mo
     D       www/wp-content/languages/plugins/wordpress-importer-en_AU.po
     A       /home/pawe/site/public_html/wp-content/mu-plugins/wpmudev-hosting/misc-functions.php
     A       /home/pawe/site/public_html/wp-content/mu-plugins/wpmudev-hosting/statsd.php
     A       /home/pawe/site/public_html/wp-content/mu-plugins/wpmudev-hosting/wp-cli.php
     A       /home/pawe/site/public_html/wp-content/mu-plugins/wpmudev-hosting.php
     D       www/wp-content/plugins/jetpack/.svnignore
     D       www/wp-content/plugins/jetpack/3rd-party/3rd-party.php
     D       www/wp-content/plugins/jetpack/3rd-party/bbpress.php
     D       www/wp-content/plugins/jetpack/3rd-party/beaverbuilder.php
     D       www/wp-content/plugins/jetpack/3rd-party/bitly.php
     D       www/wp-content/plugins/jetpack/3rd-party/buddypress.php
     D       www/wp-content/plugins/jetpack/3rd-party/class.jetpack-amp-support.php
     D       www/wp-content/plugins/jetpack/3rd-party/class.jetpack-modules-overrides.php
     D       www/wp-content/plugins/jetpack/3rd-party/debug-bar/class.jetpack-search-debug-bar.php 

    The meaning of the letters in front of the filename is as follows:

    A - added file (there's a new file that wasn't in the backup)
    D - deleted file (a file that was in the backup is not on the site)
    M - modified file (file on site is different than the one in the backup)
    If you know how to read diff output, you can skip the --name-status parameter to be able to quickly check what changes are there.

    This gives you a list of changes in files. Usually shows if a plugin/theme was added/deleted etc.

    4. Prepare database files for importing

    First, check if by any chance the database prefix isn’t backup_. We don’t want to destroy any data by accident. You can do this fastest via phpmyadmin.
    While in the backup directory, run the following command (make sure to check if the sql files have the wp_ prefix inside, if not, adjust):
    sed -i.bak 's;wp_;backup_;g' *.sql
    This will update all the sql files to change the table names, because we need to import them to be next to the current tables for comparing.
    This will also create backups with .bak extension just in case something goes wrong.
    5. Import *.sql files
    We don’t have for enabled on our hosting, also PHP system and shell_exec are blocked, but we have perl, so we can use it to import all *.sql files.
    Create and upload a file named importdb.pl containing:

    use strict; use warnings;
     use autodie;  # automatic error handling
     while (defined(my $file = glob '*.sql')) {
             system("wp db import $file");

    Once uploaded, run it with:
    perl importdb.pl
    Output should look like this:

     Success: Imported from 'wp_woocommerce_api_keys.sql'.
     Success: Imported from 'wp_woocommerce_attribute_taxonomies.sql'.
     Success: Imported from 'wp_woocommerce_downloadable_product_permissions.sql'.
     Success: Imported from 'wp_woocommerce_log.sql'.
     Success: Imported from 'wp_woocommerce_order_itemmeta.sql'.
     Success: Imported from 'wp_woocommerce_order_items.sql'.
     Success: Imported from 'wp_woocommerce_payment_tokenmeta.sql'. 

    6. Compare db tables
    You can do this either from the terminal, or via phpmyadmin SQL tab.
    For terminal, run the following command to start db shell:
    Once there, select the database:
    use siteid_wpmudev_host;
    Now we can run commands to check the differences in rows between tables. If there are no differences, you should get the following output:
    Empty set (0.001 sec)
    SELECT ID, user_login FROM ( SELECT ID, user_login FROM backup_users UNION ALL SELECT ID, user_login FROM wp_users ) tbl GROUP BY ID, user_login HAVING count(*) = 1 ORDER BY ID;
    SELECT umeta_id, user_id, meta_key, meta_value FROM ( SELECT umeta_id, user_id, meta_key, meta_value FROM backup_usermeta UNION ALL SELECT umeta_id, user_id, meta_key, meta_value FROM wp_usermeta ) tbl GROUP BY umeta_id, user_id, meta_key, meta_value HAVING count(*) = 1 ORDER BY umeta_id;
    SELECT ID, post_content, post_title, post_status FROM ( SELECT ID, post_content, post_title, post_status FROM backup_posts UNION ALL SELECT ID, post_content, post_title, post_status FROM wp_posts ) tbl GROUP BY ID, post_content, post_title, post_status HAVING count(*) = 1 ORDER BY ID;
    SELECT meta_id, post_id, meta_key, meta_value FROM ( SELECT meta_id, post_id, meta_key, meta_value FROM backup_postmeta UNION ALL SELECT meta_id, post_id, meta_key, meta_value FROM wp_postmeta ) tbl GROUP BY meta_id, post_id, meta_key, meta_value HAVING count(*) = 1 ORDER BY meta_id;
    SELECT option_id, option_name, option_value FROM ( SELECT option_id, option_name, option_value FROM backup_options UNION ALL SELECT option_id, option_name, option_value FROM wp_options ) tbl GROUP BY option_id, option_name, option_value HAVING count(*) = 1 ORDER BY option_id;
    SELECT term_id, name, slug FROM ( SELECT term_id, name, slug FROM backup_terms UNION ALL SELECT term_id, name, slug FROM wp_terms ) tbl GROUP BY term_id, name, slug HAVING count(*) = 1 ORDER BY term_id;
    SELECT object_id, term_taxonomy_id FROM ( SELECT object_id, term_taxonomy_id FROM backup_term_relationships UNION ALL SELECT object_id, term_taxonomy_id FROM wp_term_relationships ) tbl GROUP BY object_id, term_taxonomy_id HAVING count(*) = 1 ORDER BY object_id;
    You can create additional queries for other plugins using examples above.
    7. Compare contents of database tables
    Head to phpmyadmin and do a quick check on a couple of posts contents . Look for differences between wp_posts and backup_posts. They should all be the same if the backup was restored correctly.
    Also check if the content seems good on the restored tables – if there are no encoding issues, additional escape sequences (slashes etc.), if HTML looks correctly.
    Do the similar for options, I suggest checking following options:
    Take care to check if the serialized fields like active_plugins look correctly. They should be similar to this, without additional escaping of quotes (like \”:wink: etc.:
    You can also do an additional quick check in the Backups tab for the host. It lists number of posts, pages, uploads, plugins, themes and users. You can do a comparison if there was a backup created after restoring the site.
    You can trigger creating a backup from the command line if you want:
    wp wpmudev backup create
    7. Cleanup
    If you created a staging environment, it’s enough to just delete it to clean up.
    If not, you can do this to remove all unzipped files:
    rm -rf /site/backup
    To remove all the backup_ database tables, simplest way is to go to phpmyadmin and select all the unnecessary tables, then DROP them.

    Be careful to choose the correct environment while cleaning up!

    Hope this helps!

    Kind regards,

Thank NAME, for their help.

Let NAME know exactly why they deserved these points.

Gift a custom amount of points.