简体   繁体   English

测试保存设置的升级路径

[英]Testing Upgrade Path for Saved Settings

I'm working in C# and I have a custom "settings" object in my software that's saved on disk that I need to be able to test when I upgrade versions of my software. 我正在C#中工作,我的软件中有一个自定义的“设置”对象,该对象保存在磁盘上,升级软件版本时需要进行测试。

For example, if I have software with "version A" and have settings from that version, when I upgrade to "version B" of my software, I want to make sure that "settings A" can be upgraded cleanly. 例如,如果我拥有带有“ A版”的软件,并且具有该版本的设置,那么当我升级到软件的“ B版”时,我要确保“设置A”可以完全升级。

When later I upgrade to "version C" of my software, I have to test the upgrade paths from A->C as well as B->C (version n+1 requires n+1 more test cases than version n did). 稍后,当我升级到软件的“版本C”时,我必须测试从A-> C以及B-> C的升级路径(版本n + 1比版本n多需要n + 1个测试用例)。

A large concern I have is that this exponential growth of testing paths will quickly get hard to maintain. 我主要担心的是,测试路径的这种指数增长将很快变得难以维护。

Is there a standard way of dealing with this? 有标准的处理方法吗?


Some important issues I have are: 我遇到的一些重要问题是:

The settings aren't necessarily stored on a local computer, so the software I inherited needs to be able to transfer these settings from computer to computer. 这些设置不一定存储在本地计算机上,因此我继承的软件需要能够在计算机之间传输这些设置。

MSDN says they constructs like ClickOnce settings don't support this directly, and I must "develop [my] own custom settings classes for storing settings on a remote computer." MSDN表示,它们的结构(例如ClickOnce设置)不直接支持此功能,我必须“开发[我]自己的自定义设置类,以将设置存储在远程计算机上”。

Installers must generally be run using Administrator permissions, and therefore usually have access to the network. 安装程序通常必须使用管理员权限运行,因此通常可以访问网络。 All you should need to do is access the current version's app config (or a registry key if you did it that way) and get the file location, then use a FileStream to pull it across, whether that's from the local comp, the local server, or a corporate server, as long as you can do it over the LAN/WAN. 您需要做的就是访问当前版本的应用程序配置(或注册表键,如果您这样做的话)并获取文件位置,然后使用FileStream将其拉过来(无论是来自本地组件还是本地服务器)或公司服务器,只要您可以通过LAN / WAN进行即可。 Pulls from an Internet address will require a different mechanism. 从Internet地址提取将需要不同的机制。

What I would do is layer the conversions. 我要做的是对转换进行分层。 To convert a settings file from A to D, first convert it to B, then to C, and THEN to D. This may sound non-performant, but it will only be so in cases where the user has an extremely outdated version of the software; 要将设置文件从A转换为D,请先将其转换为B,然后转换为C,再将THEN转换为D。这听起来可能效果不佳,但是只有在用户使用的版本非常过时的情况下才会如此。软件; regular updates from the previous version will only need to go through one layer. 较早版本的常规更新将只需要经过一层即可。 It also has the extreme advantage of making each layer closed to change; 它还具有使每个层都封闭以进行更改的极端优势; once you have code to correctly turn version A into version B, you NEVER have to go back in and possibly break it to add the version C update logic. 一旦有了将A版本正确转换为B版本的代码,就无需再回去并可能破坏它以添加C版本更新逻辑。

I added a comment about possibly doing this when the application first runs after an upgrade. 我添加了有关在升级后首次运行应用程序时可能执行此操作的注释。

It isn't clear to me if your concern is with having to develop all these upgrade paths or with getting this integrated into your installation/upgrade procedure. 对于您来说,是要开发所有这些升级路径还是将其集成到您的安装/升级过程中,对我来说尚不清楚。

If the issue is with how to build and test increasingly numerous settings upgrades, then a simple, relatively easy way to do it is this: 如果问题在于如何构建和测试越来越多的设置升级,那么一个简单,相对容易的方法是:

public interface ISettingsUpgrader
{
    void UpgradeSettings();
}

public abstract class SettingsUpgrader : SettingsUpgrader
{
    protected int version;

    public virtual void UpgradeSettings()
    {
        // load settings and read version info
        version = settingsVersion;
    }
}

public class SettingsUpgraderV2 : SettingsUpgrader
{
    public override void UpgradeSettings()
    {
        base.UpgradeSettings();
        if(version > 1) return;

        // do the v1 -> v2 upgrade
    }
}

public class SettingsUpgraderV3 : SettingsUpgraderV2
{
    public override void UpgradeSettings()
    {
        base.UpgradeSettings();
        if(version > 2) return;

        // do the v2 -> v3 upgrade
    }
}

So, for each new version, you only have to follow this convention and implement the upgrade from the previous version. 因此,对于每个新版本,您只需遵循此约定并实施从先前版本的升级。 All of the basic settings file handling goes in the base, abstract class, and successive upgrades will be performed as necessary. 所有基本设置文件的处理都在基类,抽象类中进行,并将根据需要执行后续升级。

Testing-wise, each new version requires only verifying (1) that the base method is called -- the functionality of which is already covered by existing tests, and (2) that the latest v(n-1) -> v(n) is properly executed. 在测试方面,每个新版本仅需要验证(1)调用了基本方法-现有测试已经涵盖了该方法的功能,以及(2)最新的v(n-1)-> v(n )已正确执行。

As an additional note, it is probably good form to also implement a settings rollback procedure at each level, unless you're disallowing the option to roll back to a previous version. 需要特别注意的是,在每个级别上也可以执行设置回滚过程,这是一个很好的形式,除非您不允许选择回滚到以前的版本。

The best way to deal with upgrades is to do it one step at a time. 应对升级的最佳方法是一次完成一个步骤。

Taking your example: Build an upgrade path from A to B, then one from B to C. 以您的示例为例:建立从A到B,然后从B到C的升级路径。

When testing an upgrade from A to C you have to run A to B first, then B to C. 测试从A到C的升级时,必须先运行A到B,然后再运行B到C。

This will limit testing scenarios quite a bit. 这将极大地限制测试方案。 A lot of software I've seen does the upgrade this way. 我见过的许多软件都是以这种方式进行升级的。 It might result in things like having a field added to a table (upgrade to B) only to have it removed immediately (upgrade to C); 这可能会导致诸如将字段添加到表(升级到B)只是立即将其删除(升级到C)之类的事情。 but that's a small price to pay in order to limit the scenarios down. 但这是为了降低方案数量而付出的小代价。

At the end of this you only have to build an upgrade script to take you from the immediate previous version to the current one. 最后,您只需要构建一个升级脚本,即可将您从直接的先前版本升级到当前版本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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