I set up a simple program just to test how the code inside a get accessor executes (since I had been having some issues in another project), and found something quite strange:
class Program {
static void Main(string[] args) {
var test = new TestClass();
var testBool = test.TestBool;
}
}
public class TestClass {
private bool _testBool = true;
public bool TestBool {
get {
if (_testBool) {
Console.WriteLine("true!");
} else {
Console.WriteLine("false! WTF!");
}
_testBool = false;
return _testBool;
}
}
}
I expected the output to be
true!
But what I got instead was
true!
false! WTF!
Just what is going on here?
If I had to guess, I'd say that the debugger ran it once to show the members of a local variable in the IDE.
If you have side effects in properties (which you shouldn't), don't run it in the IDE :)
Try it at the console; it should behave itself there.
No repro.
And don't write Getters with side effects.
Related
This code is created by firefox selenium:
[Test]
public void TheNB1UnitTest()
{
driver.Navigate().GoToUrl(baseURL + "/Login");
driver.FindElement(By.Id("Group")).Clear();
}
private bool IsElementPresent(By by)
{
try
{
driver.FindElement(by);
return true;
}
catch (NoSuchElementException)
{
return false;
}
}
Given that By is an object from the class org.openqa.selenium package, how is IsElementPresent(By by) even making use of it with regards to driver.FindElement(By.Id("Group")).Clear(); ??
Have a look in the source code of C# binding of Selenium
You will find the method definition for By.Id(), it is a static method:
public static By Id(string idToFind)
maybe that already answers your question? Because the method is static you don't need to "declare" anything.
and in this method you will find this line:
By by = new By();
so there is indeed a "new" object created and handed over to your IsElementPresent() method.
You can set a breakpoint in IsElementPresent to see when it is called. However in this case I guess the IsElementPresent is generated, but not used till you make some assert which use the IsElementPresent.
The IsElementPresent is generated for you to make asserts in your unit test:
public void TheNB1UnitTest()
{
driver.Navigate().GoToUrl(baseURL + "/Login");
driver.FindElement(By.Id("Group")).Clear();
Assert.IsTrue(IsElementPresent(By.<my search>));
}
after-generating-webdriver-code-how-and-where-to-modify-code
Below is my code snippet, the variable "_lastError" doesn't seem to persist after it is set then accessed elsewhere.
Can anyone give a heads up on what I missed or done incorrectly? I've debugged the program, setting a breakpoint at both the getter and the private setter. Nothing else seems to be accessing nor modifying the value of "_lastError" other than where it was intended to.
class Utils
{
private static string _lastError;
public static string LastError
{
get
{
string lastError = Utils._lastError;
Utils._lastError = string.Empty;
return lastError;
}
private set
{
Utils._lastError = value;
}
}
public static void Foo()
{
try { // .... // }
catch (Exception ex)
{
Utils.LastError = ex.Message;
}
}
}
If the intended behavior is to hold the last error until it's accessed once, then the way you describe it acting is expected.
If the intended behavior is to hold onto the last error until another newer error overwrites it, James's point is important to remember. You're clearing the static value once it's accessed, which as Patrick pointed out affects your view in the debugger. The debugger enumerates all properties, because properties aren't intended to have side effects like wiping out the data that backs them.
Is there any way to make this method return true under a certain condition during runtime? Quick note: All I want to know is if this is at all possible. Trust me, alternative ways of writing the method won't help.
public bool Example()
{
return false;
}
if(//Certain condition is satisfied)
{
//Example method returns true instead
}
Yes. I occasionally have to do this. Here's what I do:
Attach a CLR profiler to the process before it starts.
Set the profiler to be called back when Example is jitted.
Do IL injection to replace its contents with the code of my choice.
Now I control whether the method returns true or false.
Something like this?
public bool Example()
{
if(//Certain condition is satisfied)
{
return true;
}
return false;
}
Trust me, alternative ways of writing the method won't help.
I beg to differ. Perhaps if you explain your actual problem, instead of your attempted solution, a more accurate answer can be given.
public bool Example()
{
return Certaincondition;
}
Without knowing your case, why don't you just create an interface and two implementations (an implementation that returns true and an implementation that returns false); and use the correct implementation based on your if-statement?
public interface IMyInterface
{
public bool MyMethod();
}
public class Impl1 : IMyInterface
{
public bool MyMethod()
{
return true;
}
}
public class Impl2 : IMyInterface
{
public bool MyMethod()
{
return false;
}
}
// in your logic somewhere
if(//Certain condition is satisfied)
{
new Impl1().MyMethod();
} else
{
new Impl2().MyMethod();
}
Trying a shot to a little advanced text adventure here, I have an inventory class. (isn't an error) and it all works great!
I'm trying to implement a feature of an input. That it just leads to input, and then returns the arguments back to that class. I thought it would be easy. Turned out a 'void' method can't return something. I don't know what I should use then.
I searched a bit on Google but can't find google, and the answers on here are all XML or more experienced programmers. There are also a few simpler once, but those are unanswered.
This is my Program class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Inventory_system_test
{
class Program
{
//Objects
static private Inventory inv = new Inventory();
//strings
static private string args;
//variables
static void Main(string[] args)
{
Write("Do you want to kill dave?");
input();
}
static public void input()
{
bool done = false;
Writen("Enter a command: ");
args = Console.ReadLine();
while (!done)
{
if (args.Contains("add inv "))
{
args = args.Split()[2];
inv.additem(args);
}
else if (args.Contains("remove inv "))
{
args = args.Split()[2];
inv.removeitem(args);
}
else if (args.Contains("see inv"))
{
Write("INVENTORY:");
inv.getinv();
}
else if (args == "close")
{
Environment.Exit(0);
}
else
{
done = true;
return args; ///**Here is the error ofcourse.**
}
}
} //Input files things :)
#region Easy Commands (Write, Sleep)
//Write to console
public static void Write(string writev)
{
Console.WriteLine(writev);
}
//Sleep for 'int sleeptime' in milliseconds
public static void Sleep(int sleeptime)
{
System.Threading.Thread.Sleep(sleeptime);
}
public static void Writen(string writen)
{
Console.Write(writen);
}
#endregion
}
}
I'm getting to understand scripting more and more, and that's just by asking question and searching Googles, I really love the people on Stackoverflow! Thank you all for your help!
So uh.. how would I go and do this?
There aren't many methods.. And I wouldn't know what to do from here.
Turned out a 'void' method can't return something. I don't know what I should use then.
You should use a method which is declared to return the kind of information you want to return! When a method is void, that specifically means it's not meant to return anything.
In this case it looks like you're trying to return the value of args, which is a string variable, so you want:
public static string input()
Additionally:
You should follow .NET naming conventions
There's no reason for your args variable to be static - it would better as a local variable within your method
args is an odd name for this variable anyway, in my view. Given that you're asking for a command, why not use command as the variable name?
I suggest you read the MSDN page on methods or look in a good book about C# to learn more about return types, parameters and so on.
From void (C# Reference)
When used as the return type for a method, void specifies that the
method does not return a value.
But your input method returns a value so..
Console.ReadLine() methods retursn a string so your args is looks like a string. That's why you should change your return type as a string like;
public static string input()
{
}
You declare args as being of type string, so that's what you should return:
static public string input()
{
...
return args;
}
I'm on a testing team and we are writing tests for a Word Plugin. We have a start word method that we reun before each of your tests. It works fine for the individual tests but when we put them in an ordered test, it throws an exception. This is what we had before:
if (!Playback.IsInitialized)
{
Playback.Initialize();
}
// Launch '%ProgramFiles%\Microsoft Office\Office12\WINWORD.EXE'
ApplicationUnderTest wINWORDApplication = ApplicationUnderTest.Launch(exePath, altPath);
if (killAllPreviousWordProcesses == true)
{
wINWORDApplication.Maximized = true;
}
After looking around we foudn a post that suggested using Process.Start() instead of ApplicationUnderTest. This was the code they suggested.
Process np = Process.Start(#"C:\Windows\System32\Notepad.exe");
while (np.MainWindowHandle == IntPtr.Zero)
{
System.Threading.Thread.Sleep(100);
}
//This line throws the error
WinWindow npWindow = UITestControlFactory.FromWindowHandle(np.MainWindowHandle) as WinWindow;
MessageBox.Show(npWindow.Name);
ApplicationUnderTest aut = ApplicationUnderTest.FromProcess(np);
MessageBox.Show(aut.Title);
We changed it to use Word (replacing the string with "WINWORD", we've also tried the path) but now we get a NullReferenceException everytime we run the method. I've checked everything for null and made sure the np.MainWindowHandle was not zero but its still giving me the error. Any ideas to fix this or alternative suggestions?
StackTrace:
at Microsoft.VisualStudio.TestTools.UITest.Playback.ScreenElement.FindFromWindowHandle(IntPtr windowHandle)
at Microsoft.VisualStudio.TestTools.UITesting.UITestControl..ctor(IntPtr windowHandle)
at Microsoft.VisualStudio.TestTools.UITesting.UITestControl.FromWindowHandle(IntPtr windowHandle)
at Microsoft.VisualStudio.TestTools.UITesting.UITestControlFactory.FromWindowHandle(IntPtr windowHandle)
at Common.BaseUIMapClasses.BaseUIMap.startWord(Boolean killAllPreviousWordProcesses, Boolean maximizeWord, String exePath, String altPath) in C:\Source1\Common\BaseUIMap.cs:line 170
You should check this post
Thanks a lot to Nikola. I see problem is solved, but I want to share my interesting case. Let's imagine I have one test class and it's base class. Base class defines some ClassInitialize actions. Test class has CodedUITest attribute, but base class also has attribute - [TestClass]. This broke everything.
[CodedUITest]
public class ProjectTabTests : CodedUIFunctionalTestBase
{
[TestInitialize]
public override void SetUp()
{
base.SetUp();
}
[TestMethod]
public void Test()
{
}
}
[TestClass] // this broke everything! remove it!
public class CodedUIFunctionalTestBase
{
public virtual void SetUp()
{
KillProcess(Constanst.ProcessName);
Playback.PlaybackSettings.SmartMatchOptions = SmartMatchOptions.None;
Playback.PlaybackSettings.LoggerOverrideState = HtmlLoggerState.AllActionSnapshot; // here I got internal NullReferenceException
Playback.PlaybackSettings.SearchTimeout = 10000;
Playback.PlaybackSettings.WaitForReadyTimeout = 10000;
Playback.PlaybackSettings.ThinkTimeMultiplier = 1;
Playback.PlaybackSettings.MaximumRetryCount = 3;
Application = ApplicationUnderTest.Launch(Constants.Application);
}
}
Hope this post could help somebody.