Unit Testing in
SharePoint 2010
      Chris Weldon
   Dallas TechFest 2011
Before We Begin


http://slidesha.re/       http://spkr8.com/t/8140




git://github.com/neraath/testing-in-sp2010.git
Your Guide: Chris Weldon

•   Fightin’ Texas Aggie

•   .Net and PHP Developer

•   UNIX and Windows Sysadmin

•   Sr. Consultant at Improving Enterprises

•   chris@chrisweldon.net
Agile, Microsoft, Open Technologies, UX
Applied Training, Coaching, Mentoring
Certified Consulting
Rural Sourcing
Recruiting Services
Assumptions


• You develop software
• You unit test
• You know the SharePoint API (or can follow along)
Standard Testing Practices
                        A Common Problem
namespace SharePointLogic
{
    public class ClassWithDependencies
    {
        private IDataRepository repository;

        public ClassWithDependencies(IDataRepository repo)
        {
            this.repository = repo;
        }

        public INode GetNodeByName(string name)
        {
            return this.repository.Where(x => x.Name.Equals(name))
                                  .Select();
        }
    }
}
public IList<SPUser> GetUsersInSiteCollection(string siteUrl) {
  using (SPSite site = new SPSite(siteUrl) {
    site.CatchAccessDeinedError = false;

        using (SPWeb web = site.RootWeb) {
          try {
            if (web.DoesUserHavePermissions(SPBasePermissions.ManageWeb)) {
              SPUsercollection users = web.Users;
              List<SPUser> usersWithAccess = new List<SPUser>();
              foreach (SPUser user in users) {
                if (web.DoesUserHavePermissions(
                  user.LoginName, SPBasePermissions.ManageWeb)) {
                  usersWithAccess.Add(user);
                }
              }

                return usersWithAccess;
              }
            } catch (UnauthorizedAccessException e) {
              return new List<SPUser>();
            }
        }
    }
}
Standard Testing Practices
                A Common Problem



• What if no database locally?
• Did you write test logic to rebuild the database
  before each test run?

• What if this dependency is a physical piece of
  hardware?
Standard Testing Practices
                               How to Solve
namespace SharePointLogicTests
{
    [TestClass]
    public class ClassWithDependenciesTests
    {
        [TestMethod]
        public void TestGetNodesByName()
        {
            // Arrange.
            INode node = new SharePointNode();
            IDataRepository repository =
                (IDataRepository)MockRepository.Stub<IDataRepository>();
            repository.Stub(x => x.Where).Returns(repository);
            repository.Stub(x => x.Select).Returns(node);
            repository.Replay();

// ...
Standard Testing Practices
                                 How to Solve


            // Act.
            ClassWithDependencies testClass = new ClassWithDependencies(repository);
            INode testNode = testClass.GetNodeByName("Test");

            // Assert.
            Assert.AreEqual(node, testNode);
        }
    }
}
Standard Testing Practices
              What about SharePoint?


• Most of SharePoint object model has NO interfaces
• Worse, most also are Sealed classes, meaning no
  extending and overriding the SharePoint behavior

• Most SharePoint objects require active connection
  and instance of SharePoint on local server

 • Unlike database projects, resetting and recreating
    state in SharePoint is way more difficult
Standard Testing Practices
          A SharePoint Common Problem


public string GetNameOfSharePointWebSite(string url)
{
    using (SPSite site = new SPSite(url))
    {
        using (SPWeb web = site.OpenWeb())
        {
            return web.Name;
        }
    }
}
Pex and Moles
• What is it?
 • Pex discovers boundary conditions of your tests
    and automates test creation

 • Visual Studio Add In
 • Developed by Microsoft Research
 • Available for Academic or for MSDN subscribers
Pex and Moles

• Moles is, simply put, a mocking and stubbing
  framework

 • Different than other traditional mocking
    frameworks

 • Uses detours to custom delegates via runtime
    instrumentation
Pex and Moles


• Pex and Moles are not mutually exclusive
• Neither are dependent upon one another
DEMO

SharePoint & Moles
     Example
Pex and Moles
• As your dependency on SharePoint Object Model
  grows, more detours required for testing

• In most cases, more tedious than beneficial
• If only could have most of the basic SharePoint
  behaviors pre-generated

• Solution:
  Microsoft.SharePoint.Behaviors
DEMO

SharePoint Mole
   Behaviors
Observations
Observations
• Even behaviors are not complete
Observations
• Even behaviors are not complete
• A lot of mocking activity may get repeated
Observations
• Even behaviors are not complete
• A lot of mocking activity may get repeated
• Unit test setup logic gets refactored into common
  assemblies
Observations
• Even behaviors are not complete
• A lot of mocking activity may get repeated
• Unit test setup logic gets refactored into common
  assemblies

• Save time: create scenarios
Observations
• Even behaviors are not complete
• A lot of mocking activity may get repeated
• Unit test setup logic gets refactored into common
  assemblies

• Save time: create scenarios
• Use BDD-style approach for testing
Gotchas
Gotchas
• More moles unit tests = much longer test execution
  time
Gotchas
• More moles unit tests = much longer test execution
  time

• Continuous Integration
Gotchas
• More moles unit tests = much longer test execution
  time

• Continuous Integration
• This will take time to learn, research, and debug
Gotchas
• More moles unit tests = much longer test execution
  time

• Continuous Integration
• This will take time to learn, research, and debug
 • Pay attention when it stops adding value
Gotchas
• More moles unit tests = much longer test execution
  time

• Continuous Integration
• This will take time to learn, research, and debug
 • Pay attention when it stops adding value
• The GAC
Gotchas
• More moles unit tests = much longer test execution
  time

• Continuous Integration
• This will take time to learn, research, and debug
 • Pay attention when it stops adding value
• The GAC
Recommendations
Recommendations

• If you can do it, build a facade in front of SharePoint
Recommendations

• If you can do it, build a facade in front of SharePoint
• Make sure you are producing consistent behaviors
Recommendations

• If you can do it, build a facade in front of SharePoint
• Make sure you are producing consistent behaviors
 • If you don’t know what SharePoint does,
    disassemble it
Q&A
Thank You!


http://slidesha.re/       http://spkr8.com/t/8140




git://github.com/neraath/testing-in-sp2010.git

Unit Testing in SharePoint 2010

  • 1.
    Unit Testing in SharePoint2010 Chris Weldon Dallas TechFest 2011
  • 2.
    Before We Begin http://slidesha.re/ http://spkr8.com/t/8140 git://github.com/neraath/testing-in-sp2010.git
  • 3.
    Your Guide: ChrisWeldon • Fightin’ Texas Aggie • .Net and PHP Developer • UNIX and Windows Sysadmin • Sr. Consultant at Improving Enterprises • chris@chrisweldon.net
  • 4.
    Agile, Microsoft, OpenTechnologies, UX Applied Training, Coaching, Mentoring Certified Consulting Rural Sourcing Recruiting Services
  • 5.
    Assumptions • You developsoftware • You unit test • You know the SharePoint API (or can follow along)
  • 6.
    Standard Testing Practices A Common Problem namespace SharePointLogic { public class ClassWithDependencies { private IDataRepository repository; public ClassWithDependencies(IDataRepository repo) { this.repository = repo; } public INode GetNodeByName(string name) { return this.repository.Where(x => x.Name.Equals(name)) .Select(); } } }
  • 7.
    public IList<SPUser> GetUsersInSiteCollection(stringsiteUrl) { using (SPSite site = new SPSite(siteUrl) { site.CatchAccessDeinedError = false; using (SPWeb web = site.RootWeb) { try { if (web.DoesUserHavePermissions(SPBasePermissions.ManageWeb)) { SPUsercollection users = web.Users; List<SPUser> usersWithAccess = new List<SPUser>(); foreach (SPUser user in users) { if (web.DoesUserHavePermissions( user.LoginName, SPBasePermissions.ManageWeb)) { usersWithAccess.Add(user); } } return usersWithAccess; } } catch (UnauthorizedAccessException e) { return new List<SPUser>(); } } } }
  • 8.
    Standard Testing Practices A Common Problem • What if no database locally? • Did you write test logic to rebuild the database before each test run? • What if this dependency is a physical piece of hardware?
  • 9.
    Standard Testing Practices How to Solve namespace SharePointLogicTests { [TestClass] public class ClassWithDependenciesTests { [TestMethod] public void TestGetNodesByName() { // Arrange. INode node = new SharePointNode(); IDataRepository repository = (IDataRepository)MockRepository.Stub<IDataRepository>(); repository.Stub(x => x.Where).Returns(repository); repository.Stub(x => x.Select).Returns(node); repository.Replay(); // ...
  • 10.
    Standard Testing Practices How to Solve // Act. ClassWithDependencies testClass = new ClassWithDependencies(repository); INode testNode = testClass.GetNodeByName("Test"); // Assert. Assert.AreEqual(node, testNode); } } }
  • 11.
    Standard Testing Practices What about SharePoint? • Most of SharePoint object model has NO interfaces • Worse, most also are Sealed classes, meaning no extending and overriding the SharePoint behavior • Most SharePoint objects require active connection and instance of SharePoint on local server • Unlike database projects, resetting and recreating state in SharePoint is way more difficult
  • 12.
    Standard Testing Practices A SharePoint Common Problem public string GetNameOfSharePointWebSite(string url) { using (SPSite site = new SPSite(url)) { using (SPWeb web = site.OpenWeb()) { return web.Name; } } }
  • 13.
    Pex and Moles •What is it? • Pex discovers boundary conditions of your tests and automates test creation • Visual Studio Add In • Developed by Microsoft Research • Available for Academic or for MSDN subscribers
  • 14.
    Pex and Moles •Moles is, simply put, a mocking and stubbing framework • Different than other traditional mocking frameworks • Uses detours to custom delegates via runtime instrumentation
  • 15.
    Pex and Moles •Pex and Moles are not mutually exclusive • Neither are dependent upon one another
  • 16.
  • 17.
    Pex and Moles •As your dependency on SharePoint Object Model grows, more detours required for testing • In most cases, more tedious than beneficial • If only could have most of the basic SharePoint behaviors pre-generated • Solution: Microsoft.SharePoint.Behaviors
  • 18.
  • 19.
  • 20.
  • 21.
    Observations • Even behaviorsare not complete • A lot of mocking activity may get repeated
  • 22.
    Observations • Even behaviorsare not complete • A lot of mocking activity may get repeated • Unit test setup logic gets refactored into common assemblies
  • 23.
    Observations • Even behaviorsare not complete • A lot of mocking activity may get repeated • Unit test setup logic gets refactored into common assemblies • Save time: create scenarios
  • 24.
    Observations • Even behaviorsare not complete • A lot of mocking activity may get repeated • Unit test setup logic gets refactored into common assemblies • Save time: create scenarios • Use BDD-style approach for testing
  • 25.
  • 26.
    Gotchas • More molesunit tests = much longer test execution time
  • 27.
    Gotchas • More molesunit tests = much longer test execution time • Continuous Integration
  • 28.
    Gotchas • More molesunit tests = much longer test execution time • Continuous Integration • This will take time to learn, research, and debug
  • 29.
    Gotchas • More molesunit tests = much longer test execution time • Continuous Integration • This will take time to learn, research, and debug • Pay attention when it stops adding value
  • 30.
    Gotchas • More molesunit tests = much longer test execution time • Continuous Integration • This will take time to learn, research, and debug • Pay attention when it stops adding value • The GAC
  • 31.
    Gotchas • More molesunit tests = much longer test execution time • Continuous Integration • This will take time to learn, research, and debug • Pay attention when it stops adding value • The GAC
  • 32.
  • 33.
    Recommendations • If youcan do it, build a facade in front of SharePoint
  • 34.
    Recommendations • If youcan do it, build a facade in front of SharePoint • Make sure you are producing consistent behaviors
  • 35.
    Recommendations • If youcan do it, build a facade in front of SharePoint • Make sure you are producing consistent behaviors • If you don’t know what SharePoint does, disassemble it
  • 36.
  • 37.
    Thank You! http://slidesha.re/ http://spkr8.com/t/8140 git://github.com/neraath/testing-in-sp2010.git

Editor's Notes