Parameterized Tests with VS2010 Test Tools - silverlight

Is it possible to write parameterized tests using VS2010 Test Tools for Silverlight?
In a regular NUnit test this would be done using TestCase attributes...
[Test]
[TestCase("myParam1")]
[TestCase("myParam2")]
[TestCase("myParam3")]
public void TestSomethingWithParameters(string myParam)
{
// ...some tests using myParam
}
Is this possible using VS2010 Test Tools?

No, this is not possible. The next best thing is to use data driven tests e.g.
http://callumhibbert.blogspot.com/2009/07/data-driven-tests-with-mstest.html
Check out the MSDN documentation also.

You can create a base class with the test method and the parameters as virtual properties.
When you inherit from this class you only need to override the properties with the desired values.
Please see the sample code:
public class Operation
{
public static int Add(int x, int y)
{
return x + y;
}
}
[TestClass]
public class AddTests : WorkItemTest
{
protected virtual int First{get { return 0; }}
protected virtual int Second{get { return 0; }}
[TestInitialize]
public virtual void Init()
{
//Init code
}
[TestCleanup]
public virtual void Clean()
{
//Clean code
}
[TestMethod]
[Description("x+y = y+x")]
public virtual void Test_operation_commutativity()
{
Assert.AreEqual(Operation.Add(Second, First), Operation.Add(First, Second));
}
}
[TestClass]
public class AddPositiveTest : AddTests
{
protected override int First { get { return 1; } }
protected override int Second { get { return 2; } }
}
[TestClass]
public class AddNegativeTest : AddTests
{
protected override int First { get { return -1; } }
protected override int Second { get { return -2; } }
}

Related

mvvm update calculated fields

Do you know best practices in wpf+mvvm to update Calculated fields?
What I can do instead OnPropertyChanged(nameof(Summary))?
Also calculated field can be in another viewmodel and this viewmodel should not know about all dependences.
This is my code :
public class Model
{
public int Prop1 { get; set; }
public int Prop2 { get; set; }
public int Summary => Prop1 + Prop2;
}
public class ViewModel : BaseViewModel
{
public Model Model { get; }
public int Prop1
{
get
{
return Model.Prop1;
}
set
{
Model.Prop1 = value;
OnPropertyChanged();
OnPropertyChanged(nameof(Summary));
}
}
public int Prop2
{
get
{
return Model.Prop2;
}
set
{
Model.Prop2 = value;
OnPropertyChanged();
OnPropertyChanged(nameof(Summary));
}
}
public int Summary => Model.Summary;
}
Calling OnPropertyChanged on the calculated property is perfectly acceptable. If you have a relatively simple model like the one you wrote that'll be enough.
If you have multiple calculated properties on the model, you might consider creating a method to call all of them from a single place, instead of calling each one from every property.
Something like this:
public int Prop1
{
get
{
return _prop1;
}
set
{
_prop1 = value;
OnPropertyChanged();
NotifyCalculatedProperties();
}
}
public int Calc1 { get { /* ... */ } }
public int Calc2 { get { /* ... */ } }
public int Calc3 { get { /* ... */ } }
public void NotifyCalculatedProperties()
{
OnPropertyChanged(nameof(Calc1));
OnPropertyChanged(nameof(Calc2));
OnPropertyChanged(nameof(Calc3));
}
In case the calculated properties exist in a different model, you can register in that Model\VM to the source's PropertyChanged event, and then invoke the change notification there.
Like that:
void ModelPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if(e.PropertyName == "Prop1")
OnPropertyChanged(nameof(Calc1));
OnPropertyChanged(nameof(Calc2));
OnPropertyChanged(nameof(Calc3));
}
Just don't forget to unsubscribe when the Model\VM changes, or you'll have a memory leak on your hands.
Lastly, you can always use the Messenger to pass messages between unrelated VMs, though you should use caution since it's a very powerful tool, and can easily be misused.
I don't know what MVVM framework you're using, but each has it's own implementation. You can find more general details on the Messenger pattern here: https://msdn.microsoft.com/en-us/magazine/jj694937.aspx

testng how to dynamically set groups from Factory?

Before I setup a test class like the code below:
1. the Factory and test Dataprovider both used excel as the dataprovider.
2. In the Factory dataprovider table, it has a list of url
3. Each time, it will find one of the url in the factory dataprovider table, and run the test in each test methods..
public class Test {
WebDriver driver;
private String hostName;
private String url;
#Factory(dataProvider = "xxxx global variables", dataProviderClass = xxxx.class)
public GetVariables(String hostName, String url) {
this.hostName = hostName;
this.url = url;
}
#BeforeMethod
#Parameters("browser")
public void start(String browser) throws Exception {
driver = new FirefoxDriver();
driver.get(url);
Thread.sleep(1000);
}
#Test(priority = 10, dataProvider = "dataprovider Test A", dataProviderClass = xxx.class)
public void TestA(Variable1,
Variable2,Variable3) throws Exception {
some test here...
}
#Test(priority = 20, dataProvider = "dataprovider Test B", dataProviderClass = xxx.class)
public void TestB(Variable1,
Variable2,Variable3)
throws Exception {
some test here...
}
#AfterMethod
public void tearDown() {
driver.quit();
}
Now I want to dynamically assign different group for each test for different url. I am thinking add a variable 'flag' in the #Factory dataprovider:
#Factory(dataProvider = "xxxx global variables", dataProviderClass = xxxx.class)
public GetVariables(String hostName, String url, String flag) {
this.hostName = hostName;
this.url = url;
this.flag = flag;
}
That when flag.equals("A"), it will only run test cases in test groups={"A"}.
When flag.equals("B"), it will only run test cases in test groups ={"B"},
When flag.equals("A,B"), it will only run test cases in test groups ={"A","B"}
Is there any way I can do that?
Thank you!
TestNG groups provides "flexibility in how you partition your tests" but it isn't for conditional test sets. For that you simply use plain old Java.
You can use inheritance or composition (I recommend the latter, see Item 16: Favor composition over inheritance from Effective Java).
Either way the general idea is the same: use a Factory to create your test class instances dynamically creating the appropriate class type with the appropriate test annotations and/or methods that you want to run.
Examples:
Inheritance
import org.testng.annotations.Factory;
import org.testng.annotations.Test;
public class DemoTest {
#Factory
public static Object[] createTests() {
return new Object[]{
new FlavorATest(),
new FlavorBTest(),
new FlavorABTest()
};
}
/**
* Base test class with code for both A-tests and B-tests.
*
* Note that none of these test methods are annotated as tests so that
* subclasses may pick which ones to annotate.
*/
public static abstract class BaseTest {
protected void testA() {
// test something specific to flavor A
}
protected void testB() {
// test something specific to flavor B
}
}
// extend base but only annotate A-tests
public static class FlavorATest extends BaseTest {
#Test
#Override
public void testA() {
super.testA();
}
}
// extend base but only annotate B-tests
public static class FlavorBTest extends BaseTest {
#Test
#Override
public void testB() {
super.testB();
}
}
// extend base and annotate both A-tests and B-tests
public static class FlavorABTest extends BaseTest {
#Test
#Override
public void testA() {
super.testA();
}
#Test
#Override
public void testB() {
super.testB();
}
}
}
Composition
import org.testng.annotations.Factory;
import org.testng.annotations.Test;
public class DemoTest {
#Factory
public static Object[] createTests() {
return new Object[]{
new FlavorATest(),
new FlavorBTest(),
new FlavorABTest()
};
}
private static void testA() {
// test something specific to flavor A
}
private static void testB() {
// test something specific to flavor B
}
// only create A-test methods and delegate to shared code above
public static class FlavorATest {
#Test
public void testA() {
DemoTest.testA();
}
}
// only create B-test methods and delegate to shared code above
public static class FlavorBTest {
#Test
public void testB() {
DemoTest.testB();
}
}
// create A-test and B-test methods and delegate to shared code above
public static class FlavorABTest {
#Test
public void testA() {
DemoTest.testA();
}
#Test
public void testB() {
DemoTest.testB();
}
}
}
Your factory methods won't be as simple as you'll need to use your "flag" from your test data to switch off of and create instances of the appropriate test classes.

How to use different behaviours in the same ViewModel?

I have the view designed for the long running tasks. It has a header and a progress bar.
So the model has the text for a header and a counter for a progress bar and a TotalAmountOfWork field. The model also has
public delegate void TaskCompleted(string resultDescription);
public event TaskCompletedCopyingCompletedEvent;
public event Action UpdateViewState;
When counters change the model invokes UpdateViewState.
ViewModel is subscribed for the events and updates in it's turn the view.
Ok. I have two classes intended to copy files from a hard disk to a flash drive and one class intended for diagnostic information retrieving and this information should be copied to a flash drive finally too.
I want to use them in the same ViewModel, but I can't figure out how to avoid code repeating. I can't figure out how to make it relying on the proper object oriented design.
Those three classes could implement an interface like this:
interface ILongRunningTask {
void DoWork();
}
And then I can implement ViewModel taking ILongRunningTask as an argument.
But look at the name of the name of the interface. It looks too generalized. It seems that something wrong with such an abstraction.
Ok. It seems to me that ViewModel should take a delegate in order to invoke a long running task. But in this case how the ViewModel will interact with the model updating it's properties?
//update
Now, model looks like:
public class FilesCopyingModel : IFilesCopier {
protected int filesCountToCopy;
public int FilesCountToCopy {
get { return filesCountToCopy; }
set {
filesCountToCopy = value;
InvokeUpdateViewState();
}
}
protected int currentProgressValue;
public int CurrentProgressValue {
get { return currentProgressValue; }
set {
currentProgressValue = value;
InvokeUpdateViewState();
}
}
public delegate void CopyingCompleted(string resultDescription);
public event CopyingCompleted CopyingCompletedEvent;
public event Action UpdateViewState;
private readonly IFilesCopier filesCopier;
protected FilesCopyingModel() {
}
public FilesCopyingModel(IFilesCopier filesCopier) {
if (filesCopier == null)
throw new ArgumentNullException("filesCopier");
this.filesCopier = filesCopier;
}
protected static string GetCurrentDateTime() {
return DateTime.Now.ToString("dd.MM.yyyy hh.mm.ss");
}
protected void InvokeCopyCompletedEvent(string resultDescription) {
if (CopyingCompletedEvent != null)
CopyingCompletedEvent(resultDescription);
}
protected void InvokeUpdateViewState() {
if (UpdateViewState != null)
UpdateViewState();
}
protected DriveInfo GetFirstReadyRemovableDrive() {
return
DriveInfo.GetDrives()
.FirstOrDefault(driveInfo => driveInfo.DriveType == DriveType.Removable && driveInfo.IsReady);
}
public void Copy() {
filesCopier.Copy();
}
}
public interface IFilesCopier {
void Copy();
}
public class KFilesCopier : FilesCopyingModel, IFilesCopier {
private string destinationKFilesDirPath;
public new void Copy() {
//some code
}
private static string ComposeDestinationKFilesDirPath(DriveInfo drive) {
//some code
}
}
public class LogsDirCopier : FilesCopyingModel, IFilesCopier {
public readonly string LogsDirPath;
public LogsDirCopier() {
//some code
}
public new void Copy() {
//some code
}
private void InternalCopyLogsDir(string destinationPath) {
//some code
}
private static void CloseStorer(ZipStorer zipStorer) {
//some code
}
private static string ComposeDestinationArchiveFilePath(string destinationPath) {
//some code
}
private void DetermineLogFilesCount() {
//some code
}
ViewModel interact with infrastructure above like this:
public class FilesCopyingViewModel: Screen {
private readonly FilesCopyingModel model;
private readonly IWindowManager windowManager;
public int CurrentProgress {
get { return model.CurrentProgressValue; }
}
public int FilesCountToCopy {
get { return model.FilesCountToCopy; }
}
[ImportingConstructor]
public LongRunningViewModel(IFilesCopier copier) {
model = copier as FilesCopyingModel;
model.CopyingCompletedEvent += CopyingCompletedHandler;
model.UpdateViewState += UpdateViewStateHandler;
windowManager = new WindowManager();
}
private void UpdateViewStateHandler() {
NotifyOfPropertyChange(() => CurrentProgress);
NotifyOfPropertyChange(() => FilesCountToCopy);
}
private void CopyingCompletedHandler(string resultDescription) {
//some code
}
private void RemoveDriveSafely() {
//some code
}
private void PromptEjection(string result) {
//some code
}
private void PromptSuccessEjection() {
//some code
}
private void PromptEjectFlashError() {
//some code
}
protected override void OnActivate() {
try {
var copier = (IFilesCopier) model;
Task.Factory.StartNew(copier.Copy);
}
catch (Exception ex) {
//error handling
}
}
}
These two classes use "Copy" as the name of the method. Now I want to add one more class with very similar behavior, but it seems that it's method should be named like "CollectDiagnosticInfo". Or maybe I can add a class DiagnosticInfoCopier:IFilesCopier and then just do the same. I really don't know, but the sixth sense suggests that there is a smell of some kind.

Store custom class instance in IsolatedStorage in Silverlight

I need to store different objects in IsolatedStorage and i'm using IsolatedStorageSettings class to do that. Some of that objects are base types so stored and retrieved well. But some of them are custom classes instances and they stored well, but when i try to retrieve them i get instances with the initial values.
How can i store custom classes instances in IsolatedStorage and retrieve them?
Phil Sandler, i guess so. but i don't know what type of serialization use isolated storage, so i don't know how to make my class serializable. Private fields also must be stored.
Here is the code of custom class:
public class ExtentHistory : INotifyPropertyChanged
{
private const int Capacity = 20;
private List<Envelope> _extents;
private int _currentPosition;
public event PropertyChangedEventHandler PropertyChanged;
public int ItemsCount
{
get { return _extents.Count; }
}
public bool CanStepBack
{
get { return _currentPosition > 0; }
}
public bool CanStepForward
{
get { return _currentPosition < _extents.Count - 1; }
}
public Envelope CurrentExtent
{
get { return (_extents.Count > 0) ? _extents[_currentPosition] : null; }
}
public ExtentHistory()
{
_extents = new List<Envelope>();
_currentPosition = -1;
}
public void Add(Envelope extent)
{
if (_extents.Count > Capacity)
{
_extents.RemoveAt(0);
_currentPosition--;
}
_currentPosition++;
while (_extents.Count > _currentPosition)
{
_extents.RemoveAt(_currentPosition);
}
_extents.Add(extent);
}
public void StepBack()
{
if (CanStepBack)
{
_currentPosition--;
NotifyPropertyChanged("CurrentExtent");
}
}
public void StepForward()
{
if (CanStepForward)
{
_currentPosition++;
NotifyPropertyChanged("CurrentExtent");
}
}
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
And here are the functions of storing and retrieving:
private IsolatedStorageSettings _storage;
public void Store(string key, object value)
{
if (!_storage.Contains(key))
{
_storage.Add(key, value);
}
else
{
_storage[key] = value;
}
}
public object Retrieve(string key)
{
return _storage.Contains(key) ? _storage[key] : null;
}
I don't want to serialize manually every object to add, i want to make custom class serializable by default to store it in isolated storage (if it's possible)
My inital guess would be a serialization problem. Do all your properties have public setters? Post the classes you are storing and the code you are using to store them.
I believe IsolatedStorageSettings uses the DataContractSerializer by default. If you want ExtentHistory to be serialized, you should read up on what you need to do to get it to work properly with this serializer:
DataContractSerializer Class
You might create a separate object strictly for the purpose of storing the data in Isolated storage (sort of like a DTO). This will allow you to keep ExtentHistory as-is.

How to register custom module manager in PRISM?

I've created some simple custom ModuleManager in my silverlight application based on PRISM. I also registered this type in bootstrapper, but PRISM still use the default manager. The constructor of my CustomModuleManager is called, but the property ModuleTypeLoaders is never accessed. I can't figure it out, how can I make it work properly?
Here is bootstrapper.cs
protected override void ConfigureContainer()
{
Container.RegisterType<IShellProvider, Shell>();
Container.RegisterType<IModuleManager, CustomModuleManager>();
base.ConfigureContainer();
}
CustomModuleManager.cs
public class CustomModuleManager : ModuleManager
{
IEnumerable<IModuleTypeLoader> _typeLoaders;
public CustomModuleManager(IModuleInitializer moduleInitializer,
IModuleCatalog moduleCatalog,
ILoggerFacade loggerFacade)
: base(moduleInitializer, moduleCatalog, loggerFacade)
{
MessageBox.Show("ctor");
}
public override IEnumerable<IModuleTypeLoader> ModuleTypeLoaders
{
get
{
MessageBox.Show("getter");
if (_typeLoaders == null)
{
_typeLoaders = new List<IModuleTypeLoader>
{
new CustomXapModuleTypeLoader()
};
}
return _typeLoaders;
}
set
{
MessageBox.Show("setter");
_typeLoaders = value;
}
}
}
CustomXapModuleTypeLoader.cs
public class CustomXapModuleTypeLoader : XapModuleTypeLoader
{
protected override IFileDownloader CreateDownloader()
{
return new CustomFileDownloader();
}
}
CustomFileDownloader.cs
public class CustomFileDownloader : IFileDownloader
{
public event EventHandler<DownloadCompletedEventArgs> DownloadCompleted;
readonly FileDownloader _dler = new FileDownloader();
public CustomFileDownloader()
{
_dler.DownloadCompleted += DlerDownloadCompleted;
}
void DlerDownloadCompleted(object sender, DownloadCompletedEventArgs e)
{
_dler.DownloadCompleted -= DlerDownloadCompleted;
if (DownloadCompleted != null)
{
if (e.Cancelled || e.Error != null)
{
DownloadCompleted(this, e);
}
else
{
DownloadCompleted(this,
new DownloadCompletedEventArgs(e.Result,
e.Error,
e.Cancelled,
e.UserState));
}
}
}
public void DownloadAsync(Uri uri, object userToken)
{
_dler.DownloadAsync(uri, userToken);
}
}
Reorder your call to base.ConfigureContainer so that yours wins (last one wins):
protected override void ConfigureContainer()
{
base.ConfigureContainer();
Container.RegisterType<IShellProvider, Shell>();
Container.RegisterType<IModuleManager, CustomModuleManager>();
}

Resources